refactor: fix sonarcloud "use enum class" code smells (#2590)
* refactor: prefer constexpr over enum for GUI_PAD values * refactor: prefer constexpr over enum for PrefsDialog values * refactor: prefer constexpr over enum for StatsDialog values * refactor: use enum class for GtrUnicode types * refactor: prefer constexpr over enum for BT peer msg codes * refactor: use enum class for TrMakemetaResult * refactor: prefer constexpr over enum for BT metadata message types * refactor: use enum class for AwaitingBt * refactor: use enum class for EncryptionPreference * refactor: use enum class for TrFormat in rpcimpl * refactor: prefer constexpr over enum for QApp intervals * refactor: prefer constexpr over enum for tr_resume bitfields * refactor: prefer constexpr over enum for Qt/TrFileModel bitfields * refactor: remove obsolete TODO comment in announce-list
This commit is contained in:
parent
a92af9193e
commit
318d60b72d
|
@ -933,7 +933,7 @@ void Application::Impl::on_app_exit()
|
|||
void Application::Impl::show_torrent_errors(Glib::ustring const& primary, std::vector<std::string>& files)
|
||||
{
|
||||
std::ostringstream s;
|
||||
auto const leader = files.size() > 1 ? gtr_get_unicode_string(GTR_UNICODE_BULLET) : "";
|
||||
auto const leader = files.size() > 1 ? gtr_get_unicode_string(GtrUnicode::Bullet) : "";
|
||||
|
||||
for (auto const& f : files)
|
||||
{
|
||||
|
|
|
@ -49,10 +49,7 @@ private:
|
|||
void add_control(guint row, Gtk::Widget& control);
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GUI_PAD_SMALL = 3,
|
||||
GUI_PAD = 6,
|
||||
GUI_PAD_BIG = 12,
|
||||
GUI_PAD_LARGE = 12
|
||||
};
|
||||
auto inline constexpr GUI_PAD_SMALL = int{ 3 };
|
||||
auto inline constexpr GUI_PAD = int{ 6 };
|
||||
auto inline constexpr GUI_PAD_BIG = int{ 12 };
|
||||
auto inline constexpr GUI_PAD_LARGE = int{ 12 };
|
||||
|
|
|
@ -641,10 +641,10 @@ void MainWindow::Impl::updateSpeeds()
|
|||
downCount += row.get_value(torrent_cols.active_peers_down);
|
||||
}
|
||||
|
||||
dl_lb_->set_text(gtr_sprintf("%s %s", tr_formatter_speed_KBps(downSpeed), gtr_get_unicode_string(GTR_UNICODE_DOWN)));
|
||||
dl_lb_->set_text(gtr_sprintf("%s %s", tr_formatter_speed_KBps(downSpeed), gtr_get_unicode_string(GtrUnicode::Down)));
|
||||
dl_lb_->set_visible(downCount > 0);
|
||||
|
||||
ul_lb_->set_text(gtr_sprintf("%s %s", tr_formatter_speed_KBps(upSpeed), gtr_get_unicode_string(GTR_UNICODE_UP)));
|
||||
ul_lb_->set_text(gtr_sprintf("%s %s", tr_formatter_speed_KBps(upSpeed), gtr_get_unicode_string(GtrUnicode::Up)));
|
||||
ul_lb_->set_visible(downCount > 0 || upCount > 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,23 +111,23 @@ bool MakeProgressDialog::onProgressDialogRefresh()
|
|||
{
|
||||
str = gtr_sprintf(_("Creating \"%s\""), base);
|
||||
}
|
||||
else if (builder_.result == TR_MAKEMETA_OK)
|
||||
else if (builder_.result == TrMakemetaResult::OK)
|
||||
{
|
||||
str = gtr_sprintf(_("Created \"%s\"!"), base);
|
||||
}
|
||||
else if (builder_.result == TR_MAKEMETA_URL)
|
||||
{
|
||||
str = gtr_sprintf(_("Error: invalid announce URL \"%s\""), builder_.errfile);
|
||||
}
|
||||
else if (builder_.result == TR_MAKEMETA_CANCELLED)
|
||||
else if (builder_.result == TrMakemetaResult::CANCELLED)
|
||||
{
|
||||
str = _("Cancelled");
|
||||
}
|
||||
else if (builder_.result == TR_MAKEMETA_IO_READ)
|
||||
else if (builder_.result == TrMakemetaResult::ERR_URL)
|
||||
{
|
||||
str = gtr_sprintf(_("Error: invalid announce URL \"%s\""), builder_.errfile);
|
||||
}
|
||||
else if (builder_.result == TrMakemetaResult::ERR_IO_READ)
|
||||
{
|
||||
str = gtr_sprintf(_("Error reading \"%s\": %s"), builder_.errfile, Glib::strerror(builder_.my_errno));
|
||||
}
|
||||
else if (builder_.result == TR_MAKEMETA_IO_WRITE)
|
||||
else if (builder_.result == TrMakemetaResult::ERR_IO_WRITE)
|
||||
{
|
||||
str = gtr_sprintf(_("Error writing \"%s\": %s"), builder_.errfile, Glib::strerror(builder_.my_errno));
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ bool MakeProgressDialog::onProgressDialogRefresh()
|
|||
/* buttons */
|
||||
set_response_sensitive(Gtk::RESPONSE_CANCEL, !builder_.isDone);
|
||||
set_response_sensitive(Gtk::RESPONSE_CLOSE, builder_.isDone);
|
||||
set_response_sensitive(Gtk::RESPONSE_ACCEPT, builder_.isDone && !builder_.result);
|
||||
set_response_sensitive(Gtk::RESPONSE_ACCEPT, builder_.isDone && builder_.result == TrMakemetaResult::OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ void MakeDialog::Impl::makeProgressDialog(std::string const& target)
|
|||
{
|
||||
progress_dialog_.reset();
|
||||
|
||||
if (!builder_->result)
|
||||
if (builder_->result == TrMakemetaResult::OK)
|
||||
{
|
||||
dialog_.hide();
|
||||
}
|
||||
|
|
|
@ -30,8 +30,5 @@ private:
|
|||
std::unique_ptr<Impl> const impl_;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAIN_WINDOW_REFRESH_INTERVAL_SECONDS = 2,
|
||||
SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS = 2
|
||||
};
|
||||
auto inline constexpr MAIN_WINDOW_REFRESH_INTERVAL_SECONDS = int{ 2 };
|
||||
auto inline constexpr SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS = int{ 2 };
|
||||
|
|
|
@ -14,10 +14,7 @@
|
|||
#include "StatsDialog.h"
|
||||
#include "Utils.h"
|
||||
|
||||
enum
|
||||
{
|
||||
TR_RESPONSE_RESET = 1
|
||||
};
|
||||
static auto constexpr TR_RESPONSE_RESET = int{ 1 };
|
||||
|
||||
class StatsDialog::Impl
|
||||
{
|
||||
|
|
|
@ -151,15 +151,15 @@ Glib::ustring getShortTransferString(
|
|||
return gtr_sprintf(
|
||||
_("%1$s %2$s %3$s %4$s"),
|
||||
tr_formatter_speed_KBps(downloadSpeed_KBps),
|
||||
gtr_get_unicode_string(GTR_UNICODE_DOWN),
|
||||
gtr_get_unicode_string(GtrUnicode::Down),
|
||||
tr_formatter_speed_KBps(uploadSpeed_KBps),
|
||||
gtr_get_unicode_string(GTR_UNICODE_UP));
|
||||
gtr_get_unicode_string(GtrUnicode::Up));
|
||||
}
|
||||
|
||||
if (bool const haveUp = haveMeta && st->peersGettingFromUs > 0; haveUp)
|
||||
{
|
||||
/* up speed, up symbol */
|
||||
return gtr_sprintf(_("%1$s %2$s"), tr_formatter_speed_KBps(uploadSpeed_KBps), gtr_get_unicode_string(GTR_UNICODE_UP));
|
||||
return gtr_sprintf(_("%1$s %2$s"), tr_formatter_speed_KBps(uploadSpeed_KBps), gtr_get_unicode_string(GtrUnicode::Up));
|
||||
}
|
||||
|
||||
if (st->isStalled)
|
||||
|
|
14
gtk/Utils.cc
14
gtk/Utils.cc
|
@ -52,20 +52,20 @@ char const* const speed_T_str = N_("TB/s");
|
|||
****
|
||||
***/
|
||||
|
||||
Glib::ustring gtr_get_unicode_string(int i)
|
||||
Glib::ustring gtr_get_unicode_string(GtrUnicode uni)
|
||||
{
|
||||
switch (i)
|
||||
switch (uni)
|
||||
{
|
||||
case GTR_UNICODE_UP:
|
||||
case GtrUnicode::Up:
|
||||
return "\xE2\x96\xB4";
|
||||
|
||||
case GTR_UNICODE_DOWN:
|
||||
case GtrUnicode::Down:
|
||||
return "\xE2\x96\xBE";
|
||||
|
||||
case GTR_UNICODE_INF:
|
||||
case GtrUnicode::Inf:
|
||||
return "\xE2\x88\x9E";
|
||||
|
||||
case GTR_UNICODE_BULLET:
|
||||
case GtrUnicode::Bullet:
|
||||
return "\xE2\x88\x99";
|
||||
|
||||
default:
|
||||
|
@ -75,7 +75,7 @@ Glib::ustring gtr_get_unicode_string(int i)
|
|||
|
||||
Glib::ustring tr_strlratio(double ratio)
|
||||
{
|
||||
return tr_strratio(ratio, gtr_get_unicode_string(GTR_UNICODE_INF).c_str());
|
||||
return tr_strratio(ratio, gtr_get_unicode_string(GtrUnicode::Inf).c_str());
|
||||
}
|
||||
|
||||
Glib::ustring tr_strlpercent(double x)
|
||||
|
|
12
gtk/Utils.h
12
gtk/Utils.h
|
@ -35,15 +35,15 @@ extern char const* const speed_M_str;
|
|||
extern char const* const speed_G_str;
|
||||
extern char const* const speed_T_str;
|
||||
|
||||
enum
|
||||
enum class GtrUnicode
|
||||
{
|
||||
GTR_UNICODE_UP,
|
||||
GTR_UNICODE_DOWN,
|
||||
GTR_UNICODE_INF,
|
||||
GTR_UNICODE_BULLET
|
||||
Up,
|
||||
Down,
|
||||
Inf,
|
||||
Bullet
|
||||
};
|
||||
|
||||
Glib::ustring gtr_get_unicode_string(int);
|
||||
Glib::ustring gtr_get_unicode_string(GtrUnicode);
|
||||
|
||||
/* return a percent formatted string of either x.xx, xx.x or xxx */
|
||||
Glib::ustring tr_strlpercent(double x);
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if 0 // TODO(ckerr): re-enable this after tr_info is made private
|
||||
#ifndef __TRANSMISSION__
|
||||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
|
|
@ -266,7 +266,7 @@ static std::vector<std::byte> getHashInfo(tr_metainfo_builder* b)
|
|||
{
|
||||
b->my_errno = error->code;
|
||||
tr_strlcpy(b->errfile, b->files[fileIndex].filename, sizeof(b->errfile));
|
||||
b->result = TR_MAKEMETA_IO_READ;
|
||||
b->result = TrMakemetaResult::ERR_IO_READ;
|
||||
tr_error_free(error);
|
||||
return {};
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ static std::vector<std::byte> getHashInfo(tr_metainfo_builder* b)
|
|||
{
|
||||
b->my_errno = error->code;
|
||||
tr_strlcpy(b->errfile, b->files[fileIndex].filename, sizeof(b->errfile));
|
||||
b->result = TR_MAKEMETA_IO_READ;
|
||||
b->result = TrMakemetaResult::ERR_IO_READ;
|
||||
tr_error_free(error);
|
||||
return {};
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ static std::vector<std::byte> getHashInfo(tr_metainfo_builder* b)
|
|||
{
|
||||
b->my_errno = EIO;
|
||||
tr_snprintf(b->errfile, sizeof(b->errfile), "error hashing piece %" PRIu32, b->pieceIndex);
|
||||
b->result = TR_MAKEMETA_IO_READ;
|
||||
b->result = TrMakemetaResult::ERR_IO_READ;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,7 @@ static std::vector<std::byte> getHashInfo(tr_metainfo_builder* b)
|
|||
|
||||
if (b->abortFlag)
|
||||
{
|
||||
b->result = TR_MAKEMETA_CANCELLED;
|
||||
b->result = TrMakemetaResult::CANCELLED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -421,12 +421,12 @@ static void tr_realMakeMetaInfo(tr_metainfo_builder* builder)
|
|||
tr_variant top;
|
||||
|
||||
/* allow an empty set, but if URLs *are* listed, verify them. #814, #971 */
|
||||
for (int i = 0; i < builder->trackerCount && builder->result == TR_MAKEMETA_OK; ++i)
|
||||
for (int i = 0; i < builder->trackerCount && builder->result == TrMakemetaResult::OK; ++i)
|
||||
{
|
||||
if (!tr_urlIsValidTracker(builder->trackers[i].announce))
|
||||
{
|
||||
tr_strlcpy(builder->errfile, builder->trackers[i].announce, sizeof(builder->errfile));
|
||||
builder->result = TR_MAKEMETA_URL;
|
||||
builder->result = TrMakemetaResult::ERR_URL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,11 +436,11 @@ static void tr_realMakeMetaInfo(tr_metainfo_builder* builder)
|
|||
{
|
||||
builder->errfile[0] = '\0';
|
||||
builder->my_errno = ENOENT;
|
||||
builder->result = TR_MAKEMETA_IO_READ;
|
||||
builder->result = TrMakemetaResult::ERR_IO_READ;
|
||||
builder->isDone = true;
|
||||
}
|
||||
|
||||
if (builder->result == TR_MAKEMETA_OK && builder->trackerCount != 0)
|
||||
if (builder->result == TrMakemetaResult::OK && builder->trackerCount != 0)
|
||||
{
|
||||
int prevTier = -1;
|
||||
tr_variant* tier = nullptr;
|
||||
|
@ -464,7 +464,7 @@ static void tr_realMakeMetaInfo(tr_metainfo_builder* builder)
|
|||
tr_variantDictAddStr(&top, TR_KEY_announce, builder->trackers[0].announce);
|
||||
}
|
||||
|
||||
if (builder->result == TR_MAKEMETA_OK && !builder->abortFlag)
|
||||
if (builder->result == TrMakemetaResult::OK && !builder->abortFlag)
|
||||
{
|
||||
if (!tr_str_is_empty(builder->comment))
|
||||
{
|
||||
|
@ -478,12 +478,12 @@ static void tr_realMakeMetaInfo(tr_metainfo_builder* builder)
|
|||
}
|
||||
|
||||
/* save the file */
|
||||
if ((builder->result == TR_MAKEMETA_OK) && (!builder->abortFlag) &&
|
||||
if ((builder->result == TrMakemetaResult::OK) && (!builder->abortFlag) &&
|
||||
(tr_variantToFile(&top, TR_VARIANT_FMT_BENC, builder->outputFile) != 0))
|
||||
{
|
||||
builder->my_errno = errno;
|
||||
tr_strlcpy(builder->errfile, builder->outputFile, sizeof(builder->errfile));
|
||||
builder->result = TR_MAKEMETA_IO_WRITE;
|
||||
builder->result = TrMakemetaResult::ERR_IO_WRITE;
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
|
@ -491,7 +491,7 @@ static void tr_realMakeMetaInfo(tr_metainfo_builder* builder)
|
|||
|
||||
if (builder->abortFlag)
|
||||
{
|
||||
builder->result = TR_MAKEMETA_CANCELLED;
|
||||
builder->result = TrMakemetaResult::CANCELLED;
|
||||
}
|
||||
|
||||
builder->isDone = true;
|
||||
|
@ -560,7 +560,7 @@ void tr_makeMetaInfo(
|
|||
|
||||
/* initialize the builder variables */
|
||||
builder->abortFlag = false;
|
||||
builder->result = TR_MAKEMETA_OK;
|
||||
builder->result = TrMakemetaResult::OK;
|
||||
builder->isDone = false;
|
||||
builder->pieceIndex = 0;
|
||||
builder->trackerCount = trackerCount;
|
||||
|
|
|
@ -13,13 +13,13 @@ struct tr_metainfo_builder_file
|
|||
uint64_t size;
|
||||
};
|
||||
|
||||
enum tr_metainfo_builder_err
|
||||
enum class TrMakemetaResult
|
||||
{
|
||||
TR_MAKEMETA_OK,
|
||||
TR_MAKEMETA_URL,
|
||||
TR_MAKEMETA_CANCELLED,
|
||||
TR_MAKEMETA_IO_READ, /* see builder.errfile, builder.my_errno */
|
||||
TR_MAKEMETA_IO_WRITE /* see builder.errfile, builder.my_errno */
|
||||
OK,
|
||||
CANCELLED,
|
||||
ERR_URL, // invalid announce URL
|
||||
ERR_IO_READ, // see builder.errfile, builder.my_errno
|
||||
ERR_IO_WRITE // see builder.errfile, builder.my_errno
|
||||
};
|
||||
|
||||
struct tr_tracker_info
|
||||
|
@ -68,7 +68,7 @@ struct tr_metainfo_builder
|
|||
uint32_t pieceIndex;
|
||||
bool abortFlag;
|
||||
bool isDone;
|
||||
tr_metainfo_builder_err result;
|
||||
TrMakemetaResult result;
|
||||
|
||||
/* file in use when result was set to _IO_READ or _IO_WRITE,
|
||||
* or the URL in use when the result was set to _URL */
|
||||
|
|
|
@ -44,36 +44,42 @@
|
|||
**/
|
||||
|
||||
// these values are hardcoded by various BEPs as noted
|
||||
enum BitTorrentMessages
|
||||
|
||||
namespace BtPeerMsgs
|
||||
{
|
||||
// http://bittorrent.org/beps/bep_0003.html#peer-messages
|
||||
BtChoke = 0,
|
||||
BtUnchoke = 1,
|
||||
BtInterested = 2,
|
||||
BtNotInterested = 3,
|
||||
BtHave = 4,
|
||||
BtBitfield = 5,
|
||||
BtRequest = 6,
|
||||
BtPiece = 7,
|
||||
BtCancel = 8,
|
||||
BtPort = 9,
|
||||
|
||||
// https://www.bittorrent.org/beps/bep_0006.html
|
||||
BtFextSuggest = 13,
|
||||
BtFextHaveAll = 14,
|
||||
BtFextHaveNone = 15,
|
||||
BtFextReject = 16,
|
||||
BtFextAllowedFast = 17,
|
||||
// http://bittorrent.org/beps/bep_0003.html#peer-messages
|
||||
auto constexpr Choke = uint8_t{ 0 };
|
||||
auto constexpr Unchoke = uint8_t{ 1 };
|
||||
auto constexpr Interested = uint8_t{ 2 };
|
||||
auto constexpr NotInterested = uint8_t{ 3 };
|
||||
auto constexpr Have = uint8_t{ 4 };
|
||||
auto constexpr Bitfield = uint8_t{ 5 };
|
||||
auto constexpr Request = uint8_t{ 6 };
|
||||
auto constexpr Piece = uint8_t{ 7 };
|
||||
auto constexpr Cancel = uint8_t{ 8 };
|
||||
auto constexpr Port = uint8_t{ 9 };
|
||||
|
||||
// http://bittorrent.org/beps/bep_0010.html
|
||||
// see also LtepMessageIds below
|
||||
BtLtep = 20
|
||||
};
|
||||
// https://www.bittorrent.org/beps/bep_0006.html
|
||||
auto constexpr FextSuggest = uint8_t{ 13 };
|
||||
auto constexpr FextHaveAll = uint8_t{ 14 };
|
||||
auto constexpr FextHaveNone = uint8_t{ 15 };
|
||||
auto constexpr FextReject = uint8_t{ 16 };
|
||||
auto constexpr FextAllowedFast = uint8_t{ 17 };
|
||||
|
||||
enum LtepMessages
|
||||
// http://bittorrent.org/beps/bep_0010.html
|
||||
// see also LtepMessageIds below
|
||||
auto constexpr Ltep = uint8_t{ 20 };
|
||||
|
||||
} // namespace BtPeerMsgs
|
||||
|
||||
namespace LtepMessages
|
||||
{
|
||||
LTEP_HANDSHAKE = 0,
|
||||
};
|
||||
|
||||
// http://bittorrent.org/beps/bep_0010.html
|
||||
auto constexpr Handshake = uint8_t{ 0 };
|
||||
|
||||
} // namespace LtepMessages
|
||||
|
||||
// http://bittorrent.org/beps/bep_0010.html
|
||||
// Client-defined extension message IDs that we tell peers about
|
||||
|
@ -82,20 +88,24 @@ enum LtepMessages
|
|||
enum LtepMessageIds
|
||||
{
|
||||
// we support peer exchange (bep 11)
|
||||
// https://www.bittorrent.org/beps/bep_0011.html
|
||||
UT_PEX_ID = 1,
|
||||
|
||||
// we support sending metadata files (bep 9)
|
||||
// https://www.bittorrent.org/beps/bep_0009.html
|
||||
// see also MetadataMsgType below
|
||||
UT_METADATA_ID = 3,
|
||||
};
|
||||
|
||||
// http://bittorrent.org/beps/bep_0009.html
|
||||
enum MetadataMsgType
|
||||
namespace MetadataMsgType
|
||||
{
|
||||
METADATA_MSG_TYPE_REQUEST = 0,
|
||||
METADATA_MSG_TYPE_DATA = 1,
|
||||
METADATA_MSG_TYPE_REJECT = 2
|
||||
};
|
||||
|
||||
auto constexpr Request = int{ 0 };
|
||||
auto constexpr Data = int{ 1 };
|
||||
auto constexpr Reject = int{ 2 };
|
||||
|
||||
} // namespace MetadataMsgType
|
||||
|
||||
// seconds between sendPex() calls
|
||||
static auto constexpr PexIntervalSecs = int{ 90 };
|
||||
|
@ -129,19 +139,19 @@ auto constexpr MaxPexPeerCount = size_t{ 50 };
|
|||
|
||||
} // unnamed namespace
|
||||
|
||||
enum
|
||||
enum class AwaitingBt
|
||||
{
|
||||
AwaitingBtLength,
|
||||
AwaitingBtId,
|
||||
AwaitingBtMessage,
|
||||
AwaitingBtPiece
|
||||
Length,
|
||||
Id,
|
||||
Message,
|
||||
Piece
|
||||
};
|
||||
|
||||
enum encryption_preference_t
|
||||
enum class EncryptionPreference
|
||||
{
|
||||
ENCRYPTION_PREFERENCE_UNKNOWN,
|
||||
ENCRYPTION_PREFERENCE_YES,
|
||||
ENCRYPTION_PREFERENCE_NO
|
||||
Unknown,
|
||||
Yes,
|
||||
No
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -355,7 +365,7 @@ public:
|
|||
|
||||
[[nodiscard]] bool is_reading_block(tr_block_index_t block) const override
|
||||
{
|
||||
return state == AwaitingBtPiece && block == torrent->blockOf(incoming.blockReq.index, incoming.blockReq.offset);
|
||||
return state == AwaitingBt::Piece && block == torrent->blockOf(incoming.blockReq.index, incoming.blockReq.offset);
|
||||
}
|
||||
|
||||
void cancel_block_request(tr_block_index_t block) override
|
||||
|
@ -589,7 +599,7 @@ public:
|
|||
* very quickly; others aren't as urgent. */
|
||||
int8_t outMessagesBatchPeriod;
|
||||
|
||||
uint8_t state = AwaitingBtLength;
|
||||
AwaitingBt state = AwaitingBt::Length;
|
||||
uint8_t ut_pex_id = 0;
|
||||
uint8_t ut_metadata_id = 0;
|
||||
uint16_t pexCount = 0;
|
||||
|
@ -597,7 +607,7 @@ public:
|
|||
|
||||
tr_port dht_port = 0;
|
||||
|
||||
encryption_preference_t encryption_preference = ENCRYPTION_PREFERENCE_UNKNOWN;
|
||||
EncryptionPreference encryption_preference = EncryptionPreference::Unknown;
|
||||
|
||||
size_t metadata_size_hint = 0;
|
||||
#if 0
|
||||
|
@ -719,7 +729,7 @@ static void protocolSendReject(tr_peerMsgsImpl* msgs, struct peer_request const*
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t) + 3 * sizeof(uint32_t));
|
||||
evbuffer_add_uint8(out, BtFextReject);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::FextReject);
|
||||
evbuffer_add_uint32(out, req->index);
|
||||
evbuffer_add_uint32(out, req->offset);
|
||||
evbuffer_add_uint32(out, req->length);
|
||||
|
@ -733,7 +743,7 @@ static void protocolSendRequest(tr_peerMsgsImpl* msgs, struct peer_request const
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t) + 3 * sizeof(uint32_t));
|
||||
evbuffer_add_uint8(out, BtRequest);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Request);
|
||||
evbuffer_add_uint32(out, req.index);
|
||||
evbuffer_add_uint32(out, req.offset);
|
||||
evbuffer_add_uint32(out, req.length);
|
||||
|
@ -748,7 +758,7 @@ static void protocolSendCancel(tr_peerMsgsImpl* msgs, peer_request const& req)
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t) + 3 * sizeof(uint32_t));
|
||||
evbuffer_add_uint8(out, BtCancel);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Cancel);
|
||||
evbuffer_add_uint32(out, req.index);
|
||||
evbuffer_add_uint32(out, req.offset);
|
||||
evbuffer_add_uint32(out, req.length);
|
||||
|
@ -764,7 +774,7 @@ static void protocolSendPort(tr_peerMsgsImpl* msgs, uint16_t port)
|
|||
|
||||
dbgmsg(msgs, "sending Port %u", port);
|
||||
evbuffer_add_uint32(out, 3);
|
||||
evbuffer_add_uint8(out, BtPort);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Port);
|
||||
evbuffer_add_uint16(out, port);
|
||||
}
|
||||
|
||||
|
@ -773,7 +783,7 @@ static void protocolSendHave(tr_peerMsgsImpl* msgs, tr_piece_index_t index)
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t) + sizeof(uint32_t));
|
||||
evbuffer_add_uint8(out, BtHave);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Have);
|
||||
evbuffer_add_uint32(out, index);
|
||||
|
||||
dbgmsg(msgs, "sending Have %u", index);
|
||||
|
@ -791,7 +801,7 @@ static void protocolSendAllowedFast(tr_peerMsgs* msgs, uint32_t pieceIndex)
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(io, out, sizeof(uint8_t) + sizeof(uint32_t));
|
||||
evbuffer_add_uint8(io, out, BtFextAllowedFast);
|
||||
evbuffer_add_uint8(io, out, BtPeerMsgs::FextAllowedFast);
|
||||
evbuffer_add_uint32(io, out, pieceIndex);
|
||||
|
||||
dbgmsg(msgs, "sending Allowed Fast %u...", pieceIndex);
|
||||
|
@ -805,7 +815,7 @@ static void protocolSendChoke(tr_peerMsgsImpl* msgs, bool choke)
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t));
|
||||
evbuffer_add_uint8(out, choke ? BtChoke : BtUnchoke);
|
||||
evbuffer_add_uint8(out, choke ? BtPeerMsgs::Choke : BtPeerMsgs::Unchoke);
|
||||
|
||||
dbgmsg(msgs, "sending %s...", choke ? "Choke" : "Unchoke");
|
||||
dbgOutMessageLen(msgs);
|
||||
|
@ -819,7 +829,7 @@ static void protocolSendHaveAll(tr_peerMsgsImpl* msgs)
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t));
|
||||
evbuffer_add_uint8(out, BtFextHaveAll);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::FextHaveAll);
|
||||
|
||||
dbgmsg(msgs, "sending HAVE_ALL...");
|
||||
dbgOutMessageLen(msgs);
|
||||
|
@ -833,7 +843,7 @@ static void protocolSendHaveNone(tr_peerMsgsImpl* msgs)
|
|||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t));
|
||||
evbuffer_add_uint8(out, BtFextHaveNone);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::FextHaveNone);
|
||||
|
||||
dbgmsg(msgs, "sending HAVE_NONE...");
|
||||
dbgOutMessageLen(msgs);
|
||||
|
@ -936,7 +946,7 @@ static void sendInterest(tr_peerMsgsImpl* msgs, bool b)
|
|||
|
||||
dbgmsg(msgs, "Sending %s", b ? "Interested" : "Not Interested");
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t));
|
||||
evbuffer_add_uint8(out, b ? BtInterested : BtNotInterested);
|
||||
evbuffer_add_uint8(out, b ? BtPeerMsgs::Interested : BtPeerMsgs::NotInterested);
|
||||
|
||||
pokeBatchPeriod(msgs, HighPriorityIntervalSecs);
|
||||
dbgOutMessageLen(msgs);
|
||||
|
@ -1104,8 +1114,8 @@ static void sendLtepHandshake(tr_peerMsgsImpl* msgs)
|
|||
auto* const payload = tr_variantToBuf(&val, TR_VARIANT_FMT_BENC);
|
||||
|
||||
evbuffer_add_uint32(out, 2 * sizeof(uint8_t) + evbuffer_get_length(payload));
|
||||
evbuffer_add_uint8(out, BtLtep);
|
||||
evbuffer_add_uint8(out, LTEP_HANDSHAKE);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Ltep);
|
||||
evbuffer_add_uint8(out, LtepMessages::Handshake);
|
||||
evbuffer_add_buffer(out, payload);
|
||||
pokeBatchPeriod(msgs, ImmediatePriorityIntervalSecs);
|
||||
dbgOutMessageLen(msgs);
|
||||
|
@ -1144,9 +1154,9 @@ static void parseLtepHandshake(tr_peerMsgsImpl* msgs, uint32_t len, struct evbuf
|
|||
auto pex = tr_pex{};
|
||||
if (tr_variantDictFindInt(&val, TR_KEY_e, &i))
|
||||
{
|
||||
msgs->encryption_preference = i != 0 ? ENCRYPTION_PREFERENCE_YES : ENCRYPTION_PREFERENCE_NO;
|
||||
msgs->encryption_preference = i != 0 ? EncryptionPreference::Yes : EncryptionPreference::No;
|
||||
|
||||
if (i != 0)
|
||||
if (msgs->encryption_preference == EncryptionPreference::Yes)
|
||||
{
|
||||
pex.flags |= ADDED_F_ENCRYPTION_FLAG;
|
||||
}
|
||||
|
@ -1248,19 +1258,19 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf
|
|||
|
||||
dbgmsg(msgs, "got ut_metadata msg: type %d, piece %d, total_size %d", int(msg_type), int(piece), int(total_size));
|
||||
|
||||
if (msg_type == METADATA_MSG_TYPE_REJECT)
|
||||
if (msg_type == MetadataMsgType::Reject)
|
||||
{
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
if (msg_type == METADATA_MSG_TYPE_DATA && !msgs->torrent->hasMetadata() && msg_end - benc_end <= METADATA_PIECE_SIZE &&
|
||||
if (msg_type == MetadataMsgType::Data && !msgs->torrent->hasMetadata() && msg_end - benc_end <= METADATA_PIECE_SIZE &&
|
||||
piece * METADATA_PIECE_SIZE + (msg_end - benc_end) <= total_size)
|
||||
{
|
||||
int const pieceLen = msg_end - benc_end;
|
||||
tr_torrentSetMetadataPiece(msgs->torrent, piece, benc_end, pieceLen);
|
||||
}
|
||||
|
||||
if (msg_type == METADATA_MSG_TYPE_REQUEST)
|
||||
if (msg_type == MetadataMsgType::Request)
|
||||
{
|
||||
if (piece >= 0 && msgs->torrent->hasMetadata() && msgs->torrent->isPublic() &&
|
||||
msgs->peerAskedForMetadataCount < MetadataReqQ)
|
||||
|
@ -1274,13 +1284,13 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf
|
|||
/* build the rejection message */
|
||||
auto v = tr_variant{};
|
||||
tr_variantInitDict(&v, 2);
|
||||
tr_variantDictAddInt(&v, TR_KEY_msg_type, METADATA_MSG_TYPE_REJECT);
|
||||
tr_variantDictAddInt(&v, TR_KEY_msg_type, MetadataMsgType::Reject);
|
||||
tr_variantDictAddInt(&v, TR_KEY_piece, piece);
|
||||
evbuffer* const payload = tr_variantToBuf(&v, TR_VARIANT_FMT_BENC);
|
||||
|
||||
/* write it out as a LTEP message to our outMessages buffer */
|
||||
evbuffer_add_uint32(out, 2 * sizeof(uint8_t) + evbuffer_get_length(payload));
|
||||
evbuffer_add_uint8(out, BtLtep);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Ltep);
|
||||
evbuffer_add_uint8(out, msgs->ut_metadata_id);
|
||||
evbuffer_add_buffer(out, payload);
|
||||
pokeBatchPeriod(msgs, HighPriorityIntervalSecs);
|
||||
|
@ -1356,7 +1366,7 @@ static void parseLtep(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer* i
|
|||
tr_peerIoReadUint8(msgs->io, inbuf, <ep_msgid);
|
||||
msglen--;
|
||||
|
||||
if (ltep_msgid == LTEP_HANDSHAKE)
|
||||
if (ltep_msgid == LtepMessages::Handshake)
|
||||
{
|
||||
dbgmsg(msgs, "got ltep handshake");
|
||||
parseLtepHandshake(msgs, msglen, inbuf);
|
||||
|
@ -1402,7 +1412,7 @@ static ReadState readBtLength(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, siz
|
|||
else
|
||||
{
|
||||
msgs->incoming.length = len;
|
||||
msgs->state = AwaitingBtId;
|
||||
msgs->state = AwaitingBt::Id;
|
||||
}
|
||||
|
||||
return READ_NOW;
|
||||
|
@ -1422,15 +1432,15 @@ static ReadState readBtId(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, size_t
|
|||
msgs->incoming.id = id;
|
||||
dbgmsg(msgs, "msgs->incoming.id is now %d; msgs->incoming.length is %zu", id, (size_t)msgs->incoming.length);
|
||||
|
||||
if (id == BtPiece)
|
||||
if (id == BtPeerMsgs::Piece)
|
||||
{
|
||||
msgs->state = AwaitingBtPiece;
|
||||
msgs->state = AwaitingBt::Piece;
|
||||
return READ_NOW;
|
||||
}
|
||||
|
||||
if (msgs->incoming.length != 1)
|
||||
{
|
||||
msgs->state = AwaitingBtMessage;
|
||||
msgs->state = AwaitingBt::Message;
|
||||
return READ_NOW;
|
||||
}
|
||||
|
||||
|
@ -1508,20 +1518,20 @@ static bool messageLengthIsCorrect(tr_peerMsgsImpl const* msg, uint8_t id, uint3
|
|||
{
|
||||
switch (id)
|
||||
{
|
||||
case BtChoke:
|
||||
case BtUnchoke:
|
||||
case BtInterested:
|
||||
case BtNotInterested:
|
||||
case BtFextHaveAll:
|
||||
case BtFextHaveNone:
|
||||
case BtPeerMsgs::Choke:
|
||||
case BtPeerMsgs::Unchoke:
|
||||
case BtPeerMsgs::Interested:
|
||||
case BtPeerMsgs::NotInterested:
|
||||
case BtPeerMsgs::FextHaveAll:
|
||||
case BtPeerMsgs::FextHaveNone:
|
||||
return len == 1;
|
||||
|
||||
case BtHave:
|
||||
case BtFextSuggest:
|
||||
case BtFextAllowedFast:
|
||||
case BtPeerMsgs::Have:
|
||||
case BtPeerMsgs::FextSuggest:
|
||||
case BtPeerMsgs::FextAllowedFast:
|
||||
return len == 5;
|
||||
|
||||
case BtBitfield:
|
||||
case BtPeerMsgs::Bitfield:
|
||||
if (msg->torrent->hasMetadata())
|
||||
{
|
||||
return len == (msg->torrent->pieceCount() >> 3) + ((msg->torrent->pieceCount() & 7) != 0 ? 1 : 0) + 1U;
|
||||
|
@ -1536,18 +1546,18 @@ static bool messageLengthIsCorrect(tr_peerMsgsImpl const* msg, uint8_t id, uint3
|
|||
|
||||
return true;
|
||||
|
||||
case BtRequest:
|
||||
case BtCancel:
|
||||
case BtFextReject:
|
||||
case BtPeerMsgs::Request:
|
||||
case BtPeerMsgs::Cancel:
|
||||
case BtPeerMsgs::FextReject:
|
||||
return len == 13;
|
||||
|
||||
case BtPiece:
|
||||
case BtPeerMsgs::Piece:
|
||||
return len > 9 && len <= 16393;
|
||||
|
||||
case BtPort:
|
||||
case BtPeerMsgs::Port:
|
||||
return len == 3;
|
||||
|
||||
case BtLtep:
|
||||
case BtPeerMsgs::Ltep:
|
||||
return len >= 2;
|
||||
|
||||
default:
|
||||
|
@ -1614,7 +1624,7 @@ static ReadState readBtPiece(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, size
|
|||
|
||||
/* cleanup */
|
||||
req->length = 0;
|
||||
msgs->state = AwaitingBtLength;
|
||||
msgs->state = AwaitingBt::Length;
|
||||
return err != 0 ? READ_ERR : READ_NOW;
|
||||
}
|
||||
|
||||
|
@ -1649,7 +1659,7 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
|
||||
switch (id)
|
||||
{
|
||||
case BtChoke:
|
||||
case BtPeerMsgs::Choke:
|
||||
dbgmsg(msgs, "got Choke");
|
||||
msgs->client_is_choked_ = true;
|
||||
|
||||
|
@ -1661,26 +1671,26 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
msgs->update_active(TR_PEER_TO_CLIENT);
|
||||
break;
|
||||
|
||||
case BtUnchoke:
|
||||
case BtPeerMsgs::Unchoke:
|
||||
dbgmsg(msgs, "got Unchoke");
|
||||
msgs->client_is_choked_ = false;
|
||||
msgs->update_active(TR_PEER_TO_CLIENT);
|
||||
updateDesiredRequestCount(msgs);
|
||||
break;
|
||||
|
||||
case BtInterested:
|
||||
case BtPeerMsgs::Interested:
|
||||
dbgmsg(msgs, "got Interested");
|
||||
msgs->peer_is_interested_ = true;
|
||||
msgs->update_active(TR_CLIENT_TO_PEER);
|
||||
break;
|
||||
|
||||
case BtNotInterested:
|
||||
case BtPeerMsgs::NotInterested:
|
||||
dbgmsg(msgs, "got Not Interested");
|
||||
msgs->peer_is_interested_ = false;
|
||||
msgs->update_active(TR_CLIENT_TO_PEER);
|
||||
break;
|
||||
|
||||
case BtHave:
|
||||
case BtPeerMsgs::Have:
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &ui32);
|
||||
dbgmsg(msgs, "got Have: %u", ui32);
|
||||
|
||||
|
@ -1700,7 +1710,7 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
updatePeerProgress(msgs);
|
||||
break;
|
||||
|
||||
case BtBitfield:
|
||||
case BtPeerMsgs::Bitfield:
|
||||
{
|
||||
auto* const tmp = tr_new(uint8_t, msglen);
|
||||
dbgmsg(msgs, "got a bitfield");
|
||||
|
@ -1712,7 +1722,7 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
break;
|
||||
}
|
||||
|
||||
case BtRequest:
|
||||
case BtPeerMsgs::Request:
|
||||
{
|
||||
struct peer_request r;
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &r.index);
|
||||
|
@ -1723,7 +1733,7 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
break;
|
||||
}
|
||||
|
||||
case BtCancel:
|
||||
case BtPeerMsgs::Cancel:
|
||||
{
|
||||
struct peer_request r;
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &r.index);
|
||||
|
@ -1752,12 +1762,12 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
break;
|
||||
}
|
||||
|
||||
case BtPiece:
|
||||
case BtPeerMsgs::Piece:
|
||||
TR_ASSERT(false); /* handled elsewhere! */
|
||||
break;
|
||||
|
||||
case BtPort:
|
||||
dbgmsg(msgs, "Got a BtPort");
|
||||
case BtPeerMsgs::Port:
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::Port");
|
||||
tr_peerIoReadUint16(msgs->io, inbuf, &msgs->dht_port);
|
||||
|
||||
if (msgs->dht_port > 0)
|
||||
|
@ -1767,8 +1777,8 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
|
||||
break;
|
||||
|
||||
case BtFextSuggest:
|
||||
dbgmsg(msgs, "Got a BtFextSuggest");
|
||||
case BtPeerMsgs::FextSuggest:
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::FextSuggest");
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &ui32);
|
||||
|
||||
if (fext)
|
||||
|
@ -1783,8 +1793,8 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
|
||||
break;
|
||||
|
||||
case BtFextAllowedFast:
|
||||
dbgmsg(msgs, "Got a BtFextAllowedFast");
|
||||
case BtPeerMsgs::FextAllowedFast:
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::FextAllowedFast");
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &ui32);
|
||||
|
||||
if (fext)
|
||||
|
@ -1799,8 +1809,8 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
|
||||
break;
|
||||
|
||||
case BtFextHaveAll:
|
||||
dbgmsg(msgs, "Got a BtFextHaveAll");
|
||||
case BtPeerMsgs::FextHaveAll:
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::FextHaveAll");
|
||||
|
||||
if (fext)
|
||||
{
|
||||
|
@ -1816,8 +1826,8 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
|
||||
break;
|
||||
|
||||
case BtFextHaveNone:
|
||||
dbgmsg(msgs, "Got a BtFextHaveNone");
|
||||
case BtPeerMsgs::FextHaveNone:
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::FextHaveNone");
|
||||
|
||||
if (fext)
|
||||
{
|
||||
|
@ -1833,10 +1843,10 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
|
||||
break;
|
||||
|
||||
case BtFextReject:
|
||||
case BtPeerMsgs::FextReject:
|
||||
{
|
||||
struct peer_request r;
|
||||
dbgmsg(msgs, "Got a BtFextReject");
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::FextReject");
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &r.index);
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &r.offset);
|
||||
tr_peerIoReadUint32(msgs->io, inbuf, &r.length);
|
||||
|
@ -1854,8 +1864,8 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
break;
|
||||
}
|
||||
|
||||
case BtLtep:
|
||||
dbgmsg(msgs, "Got a BtLtep");
|
||||
case BtPeerMsgs::Ltep:
|
||||
dbgmsg(msgs, "Got a BtPeerMsgs::Ltep");
|
||||
parseLtep(msgs, msglen, inbuf);
|
||||
break;
|
||||
|
||||
|
@ -1868,7 +1878,7 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
TR_ASSERT(msglen + 1 == msgs->incoming.length);
|
||||
TR_ASSERT(evbuffer_get_length(inbuf) == startBufLen - msglen);
|
||||
|
||||
msgs->state = AwaitingBtLength;
|
||||
msgs->state = AwaitingBt::Length;
|
||||
return READ_NOW;
|
||||
}
|
||||
|
||||
|
@ -1949,7 +1959,7 @@ static ReadState canRead(tr_peerIo* io, void* vmsgs, size_t* piece)
|
|||
{
|
||||
ret = READ_LATER;
|
||||
}
|
||||
else if (msgs->state == AwaitingBtPiece)
|
||||
else if (msgs->state == AwaitingBt::Piece)
|
||||
{
|
||||
ret = readBtPiece(msgs, in, inlen, piece);
|
||||
}
|
||||
|
@ -1957,15 +1967,15 @@ static ReadState canRead(tr_peerIo* io, void* vmsgs, size_t* piece)
|
|||
{
|
||||
switch (msgs->state)
|
||||
{
|
||||
case AwaitingBtLength:
|
||||
case AwaitingBt::Length:
|
||||
ret = readBtLength(msgs, in, inlen);
|
||||
break;
|
||||
|
||||
case AwaitingBtId:
|
||||
case AwaitingBt::Id:
|
||||
ret = readBtId(msgs, in, inlen);
|
||||
break;
|
||||
|
||||
case AwaitingBtMessage:
|
||||
case AwaitingBt::Message:
|
||||
ret = readBtMessage(msgs, in, inlen);
|
||||
break;
|
||||
|
||||
|
@ -2036,7 +2046,7 @@ static void updateMetadataRequests(tr_peerMsgsImpl* msgs, time_t now)
|
|||
/* build the data message */
|
||||
auto tmp = tr_variant{};
|
||||
tr_variantInitDict(&tmp, 3);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, METADATA_MSG_TYPE_REQUEST);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, MetadataMsgType::Request);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_piece, piece);
|
||||
auto* const payload = tr_variantToBuf(&tmp, TR_VARIANT_FMT_BENC);
|
||||
|
||||
|
@ -2044,7 +2054,7 @@ static void updateMetadataRequests(tr_peerMsgsImpl* msgs, time_t now)
|
|||
|
||||
/* write it out as a LTEP message to our outMessages buffer */
|
||||
evbuffer_add_uint32(out, 2 * sizeof(uint8_t) + evbuffer_get_length(payload));
|
||||
evbuffer_add_uint8(out, BtLtep);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Ltep);
|
||||
evbuffer_add_uint8(out, msgs->ut_metadata_id);
|
||||
evbuffer_add_buffer(out, payload);
|
||||
pokeBatchPeriod(msgs, HighPriorityIntervalSecs);
|
||||
|
@ -2135,14 +2145,14 @@ static size_t fillOutputBuffer(tr_peerMsgsImpl* msgs, time_t now)
|
|||
/* build the data message */
|
||||
auto tmp = tr_variant{};
|
||||
tr_variantInitDict(&tmp, 3);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, METADATA_MSG_TYPE_DATA);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, MetadataMsgType::Data);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_piece, piece);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_total_size, msgs->torrent->infoDictSize());
|
||||
evbuffer* const payload = tr_variantToBuf(&tmp, TR_VARIANT_FMT_BENC);
|
||||
|
||||
/* write it out as a LTEP message to our outMessages buffer */
|
||||
evbuffer_add_uint32(out, 2 * sizeof(uint8_t) + evbuffer_get_length(payload) + dataLen);
|
||||
evbuffer_add_uint8(out, BtLtep);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Ltep);
|
||||
evbuffer_add_uint8(out, msgs->ut_metadata_id);
|
||||
evbuffer_add_buffer(out, payload);
|
||||
evbuffer_add(out, data, dataLen);
|
||||
|
@ -2163,13 +2173,13 @@ static size_t fillOutputBuffer(tr_peerMsgsImpl* msgs, time_t now)
|
|||
/* build the rejection message */
|
||||
auto tmp = tr_variant{};
|
||||
tr_variantInitDict(&tmp, 2);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, METADATA_MSG_TYPE_REJECT);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, MetadataMsgType::Reject);
|
||||
tr_variantDictAddInt(&tmp, TR_KEY_piece, piece);
|
||||
evbuffer* const payload = tr_variantToBuf(&tmp, TR_VARIANT_FMT_BENC);
|
||||
|
||||
/* write it out as a LTEP message to our outMessages buffer */
|
||||
evbuffer_add_uint32(out, 2 * sizeof(uint8_t) + evbuffer_get_length(payload));
|
||||
evbuffer_add_uint8(out, BtLtep);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Ltep);
|
||||
evbuffer_add_uint8(out, msgs->ut_metadata_id);
|
||||
evbuffer_add_buffer(out, payload);
|
||||
pokeBatchPeriod(msgs, HighPriorityIntervalSecs);
|
||||
|
@ -2197,7 +2207,7 @@ static size_t fillOutputBuffer(tr_peerMsgsImpl* msgs, time_t now)
|
|||
evbuffer_expand(out, msglen);
|
||||
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t) + 2 * sizeof(uint32_t) + req.length);
|
||||
evbuffer_add_uint8(out, BtPiece);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Piece);
|
||||
evbuffer_add_uint32(out, req.index);
|
||||
evbuffer_add_uint32(out, req.offset);
|
||||
|
||||
|
@ -2323,7 +2333,7 @@ static void sendBitfield(tr_peerMsgsImpl* msgs)
|
|||
|
||||
auto bytes = msgs->torrent->createPieceBitfield();
|
||||
evbuffer_add_uint32(out, sizeof(uint8_t) + bytes.size());
|
||||
evbuffer_add_uint8(out, BtBitfield);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Bitfield);
|
||||
evbuffer_add(out, bytes.data(), std::size(bytes));
|
||||
dbgmsg(msgs, "sending bitfield... outMessage size is now %zu", evbuffer_get_length(out));
|
||||
pokeBatchPeriod(msgs, ImmediatePriorityIntervalSecs);
|
||||
|
@ -2648,7 +2658,7 @@ static void sendPex(tr_peerMsgsImpl* msgs)
|
|||
/* write the pex message */
|
||||
auto* const payload = tr_variantToBuf(&val, TR_VARIANT_FMT_BENC);
|
||||
evbuffer_add_uint32(out, 2 * sizeof(uint8_t) + evbuffer_get_length(payload));
|
||||
evbuffer_add_uint8(out, BtLtep);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Ltep);
|
||||
evbuffer_add_uint8(out, msgs->ut_pex_id);
|
||||
evbuffer_add_buffer(out, payload);
|
||||
pokeBatchPeriod(msgs, HighPriorityIntervalSecs);
|
||||
|
|
|
@ -68,9 +68,9 @@ static size_t addPeers(tr_torrent* tor, uint8_t const* buf, size_t buflen)
|
|||
return tr_peerMgrAddPex(tor, TR_PEER_FROM_RESUME, pex, n_pex);
|
||||
}
|
||||
|
||||
static uint64_t loadPeers(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadPeers(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = uint64_t{};
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
uint8_t const* str = nullptr;
|
||||
auto len = size_t{};
|
||||
|
@ -78,14 +78,14 @@ static uint64_t loadPeers(tr_variant* dict, tr_torrent* tor)
|
|||
{
|
||||
size_t const numAdded = addPeers(tor, str, len);
|
||||
tr_logAddTorDbg(tor, "Loaded %zu IPv4 peers from resume file", numAdded);
|
||||
ret = TR_FR_PEERS;
|
||||
ret = tr_resume::Peers;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindRaw(dict, TR_KEY_peers2_6, &str, &len))
|
||||
{
|
||||
size_t const numAdded = addPeers(tor, str, len);
|
||||
tr_logAddTorDbg(tor, "Loaded %zu IPv6 peers from resume file", numAdded);
|
||||
ret = TR_FR_PEERS;
|
||||
ret = tr_resume::Peers;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -105,12 +105,12 @@ static void saveLabels(tr_variant* dict, tr_torrent const* tor)
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t loadLabels(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadLabels(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
tr_variant* list = nullptr;
|
||||
if (!tr_variantDictFindList(dict, TR_KEY_labels, &list))
|
||||
{
|
||||
return 0;
|
||||
return tr_resume::fields_t{};
|
||||
}
|
||||
|
||||
int const n = tr_variantListSize(list);
|
||||
|
@ -123,7 +123,7 @@ static uint64_t loadLabels(tr_variant* dict, tr_torrent* tor)
|
|||
}
|
||||
}
|
||||
|
||||
return TR_FR_LABELS;
|
||||
return tr_resume::Labels;
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -141,9 +141,9 @@ static void saveDND(tr_variant* dict, tr_torrent const* tor)
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t loadDND(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadDND(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
auto ret = tr_resume::fields_t{};
|
||||
tr_variant* list = nullptr;
|
||||
auto const n = tor->fileCount();
|
||||
|
||||
|
@ -170,7 +170,7 @@ static uint64_t loadDND(tr_variant* dict, tr_torrent* tor)
|
|||
tor->initFilesWanted(std::data(unwanted), std::size(unwanted), false);
|
||||
tor->initFilesWanted(std::data(wanted), std::size(wanted), true);
|
||||
|
||||
ret = TR_FR_DND;
|
||||
ret = tr_resume::Dnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -201,9 +201,9 @@ static void saveFilePriorities(tr_variant* dict, tr_torrent const* tor)
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t loadFilePriorities(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadFilePriorities(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = uint64_t{};
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
auto const n = tor->fileCount();
|
||||
tr_variant* list = nullptr;
|
||||
|
@ -218,7 +218,7 @@ static uint64_t loadFilePriorities(tr_variant* dict, tr_torrent* tor)
|
|||
}
|
||||
}
|
||||
|
||||
ret = TR_FR_FILE_PRIORITIES;
|
||||
ret = tr_resume::FilePriorities;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -281,29 +281,29 @@ static void loadSingleSpeedLimit(tr_variant* d, tr_direction dir, tr_torrent* to
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t loadSpeedLimits(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadSpeedLimits(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = uint64_t{};
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
tr_variant* d = nullptr;
|
||||
if (tr_variantDictFindDict(dict, TR_KEY_speed_limit_up, &d))
|
||||
{
|
||||
loadSingleSpeedLimit(d, TR_UP, tor);
|
||||
ret = TR_FR_SPEEDLIMIT;
|
||||
ret = tr_resume::Speedlimit;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindDict(dict, TR_KEY_speed_limit_down, &d))
|
||||
{
|
||||
loadSingleSpeedLimit(d, TR_DOWN, tor);
|
||||
ret = TR_FR_SPEEDLIMIT;
|
||||
ret = tr_resume::Speedlimit;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint64_t loadRatioLimits(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadRatioLimits(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = uint64_t{};
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
if (tr_variant* d = nullptr; tr_variantDictFindDict(dict, TR_KEY_ratio_limit, &d))
|
||||
{
|
||||
|
@ -317,15 +317,15 @@ static uint64_t loadRatioLimits(tr_variant* dict, tr_torrent* tor)
|
|||
tr_torrentSetRatioMode(tor, tr_ratiolimit(i));
|
||||
}
|
||||
|
||||
ret = TR_FR_RATIOLIMIT;
|
||||
ret = tr_resume::Ratiolimit;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint64_t loadIdleLimits(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadIdleLimits(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = uint64_t{};
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
if (tr_variant* d = nullptr; tr_variantDictFindDict(dict, TR_KEY_idle_limit, &d))
|
||||
{
|
||||
|
@ -339,7 +339,7 @@ static uint64_t loadIdleLimits(tr_variant* dict, tr_torrent* tor)
|
|||
tr_torrentSetIdleMode(tor, tr_idlelimit(i));
|
||||
}
|
||||
|
||||
ret = TR_FR_IDLELIMIT;
|
||||
ret = tr_resume::Idlelimit;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -354,23 +354,26 @@ static void saveName(tr_variant* dict, tr_torrent const* tor)
|
|||
tr_variantDictAddStrView(dict, TR_KEY_name, tr_torrentName(tor));
|
||||
}
|
||||
|
||||
static uint64_t loadName(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadName(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
auto name = std::string_view{};
|
||||
if (!tr_variantDictFindStrView(dict, TR_KEY_name, &name))
|
||||
{
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
name = tr_strvStrip(name);
|
||||
if (std::empty(name))
|
||||
{
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
tor->setName(name);
|
||||
ret |= tr_resume::Name;
|
||||
|
||||
return TR_FR_NAME;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -387,12 +390,14 @@ static void saveFilenames(tr_variant* dict, tr_torrent const* tor)
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t loadFilenames(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadFilenames(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
tr_variant* list = nullptr;
|
||||
if (!tr_variantDictFindList(dict, TR_KEY_files, &list))
|
||||
{
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto const n_files = tor->fileCount();
|
||||
|
@ -406,7 +411,8 @@ static uint64_t loadFilenames(tr_variant* dict, tr_torrent* tor)
|
|||
}
|
||||
}
|
||||
|
||||
return TR_FR_FILENAMES;
|
||||
ret |= tr_resume::Filenames;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -492,10 +498,8 @@ static void saveProgress(tr_variant* dict, tr_torrent const* tor)
|
|||
* First approach (pre-2.20) had an "mtimes" list identical to
|
||||
* 3.10, but not the 'pieces' bitfield.
|
||||
*/
|
||||
static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
|
||||
static auto loadProgress(tr_variant* dict, tr_torrent* tor)
|
||||
{
|
||||
auto ret = uint64_t{};
|
||||
|
||||
if (tr_variant* prog = nullptr; tr_variantDictFindDict(dict, TR_KEY_progress, &prog))
|
||||
{
|
||||
/// CHECKED PIECES
|
||||
|
@ -616,25 +620,279 @@ static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
|
|||
tor->setBlocks(blocks);
|
||||
}
|
||||
|
||||
ret = TR_FR_PROGRESS;
|
||||
return tr_resume::Progress;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return tr_resume::fields_t{};
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void tr_torrentSaveResume(tr_torrent* tor)
|
||||
static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fieldsToLoad, bool* did_migrate_filename)
|
||||
{
|
||||
tr_variant top;
|
||||
auto fields_loaded = tr_resume::fields_t{};
|
||||
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
auto const wasDirty = tor->isDirty;
|
||||
|
||||
auto const migrated = tr_torrent_metainfo::migrateFile(
|
||||
tor->session->resume_dir,
|
||||
tor->name(),
|
||||
tor->infoHashString(),
|
||||
".resume"sv);
|
||||
if (did_migrate_filename != nullptr)
|
||||
{
|
||||
*did_migrate_filename = migrated;
|
||||
}
|
||||
|
||||
auto const filename = tor->resumeFile();
|
||||
auto buf = std::vector<char>{};
|
||||
tr_error* error = nullptr;
|
||||
auto top = tr_variant{};
|
||||
if (!tr_loadFile(buf, filename, &error) ||
|
||||
!tr_variantFromBuf(
|
||||
&top,
|
||||
TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE,
|
||||
{ std::data(buf), std::size(buf) },
|
||||
nullptr,
|
||||
&error))
|
||||
{
|
||||
tr_logAddTorDbg(tor, "Couldn't read \"%s\": %s", filename.c_str(), error->message);
|
||||
tr_error_clear(&error);
|
||||
return fields_loaded;
|
||||
}
|
||||
|
||||
tr_logAddTorDbg(tor, "Read resume file \"%s\"", filename.c_str());
|
||||
|
||||
auto boolVal = false;
|
||||
auto i = int64_t{};
|
||||
auto sv = std::string_view{};
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Corrupt) != 0 && tr_variantDictFindInt(&top, TR_KEY_corrupt, &i))
|
||||
{
|
||||
tor->corruptPrev = i;
|
||||
fields_loaded |= tr_resume::Corrupt;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & (tr_resume::Progress | tr_resume::DownloadDir)) != 0 &&
|
||||
tr_variantDictFindStrView(&top, TR_KEY_destination, &sv) && !std::empty(sv))
|
||||
{
|
||||
bool const is_current_dir = tor->current_dir == tor->download_dir;
|
||||
tor->download_dir = sv;
|
||||
if (is_current_dir)
|
||||
{
|
||||
tor->current_dir = sv;
|
||||
}
|
||||
|
||||
fields_loaded |= tr_resume::DownloadDir;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & (tr_resume::Progress | tr_resume::IncompleteDir)) != 0 &&
|
||||
tr_variantDictFindStrView(&top, TR_KEY_incomplete_dir, &sv) && !std::empty(sv))
|
||||
{
|
||||
bool const is_current_dir = tor->current_dir == tor->incomplete_dir;
|
||||
tor->incomplete_dir = sv;
|
||||
if (is_current_dir)
|
||||
{
|
||||
tor->current_dir = sv;
|
||||
}
|
||||
|
||||
fields_loaded |= tr_resume::IncompleteDir;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Downloaded) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloaded, &i))
|
||||
{
|
||||
tor->downloadedPrev = i;
|
||||
fields_loaded |= tr_resume::Downloaded;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Uploaded) != 0 && tr_variantDictFindInt(&top, TR_KEY_uploaded, &i))
|
||||
{
|
||||
tor->uploadedPrev = i;
|
||||
fields_loaded |= tr_resume::Uploaded;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::MaxPeers) != 0 && tr_variantDictFindInt(&top, TR_KEY_max_peers, &i))
|
||||
{
|
||||
tor->maxConnectedPeers = i;
|
||||
fields_loaded |= tr_resume::MaxPeers;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Run) != 0 && tr_variantDictFindBool(&top, TR_KEY_paused, &boolVal))
|
||||
{
|
||||
tor->isRunning = !boolVal;
|
||||
fields_loaded |= tr_resume::Run;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::AddedDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_added_date, &i))
|
||||
{
|
||||
tor->addedDate = i;
|
||||
fields_loaded |= tr_resume::AddedDate;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::DoneDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_done_date, &i))
|
||||
{
|
||||
tor->doneDate = i;
|
||||
fields_loaded |= tr_resume::DoneDate;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::ActivityDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_activity_date, &i))
|
||||
{
|
||||
tor->setDateActive(i);
|
||||
fields_loaded |= tr_resume::ActivityDate;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::TimeSeeding) != 0 && tr_variantDictFindInt(&top, TR_KEY_seeding_time_seconds, &i))
|
||||
{
|
||||
tor->secondsSeeding = i;
|
||||
fields_loaded |= tr_resume::TimeSeeding;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::TimeDownloading) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloading_time_seconds, &i))
|
||||
{
|
||||
tor->secondsDownloading = i;
|
||||
fields_loaded |= tr_resume::TimeDownloading;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::BandwidthPriority) != 0 && tr_variantDictFindInt(&top, TR_KEY_bandwidth_priority, &i) &&
|
||||
tr_isPriority(i))
|
||||
{
|
||||
tr_torrentSetPriority(tor, i);
|
||||
fields_loaded |= tr_resume::BandwidthPriority;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Peers) != 0)
|
||||
{
|
||||
fields_loaded |= loadPeers(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Progress) != 0)
|
||||
{
|
||||
fields_loaded |= loadProgress(&top, tor);
|
||||
}
|
||||
|
||||
// Only load file priorities if we are actually downloading.
|
||||
// If we're a seed or partial seed, loading it is a waste of time.
|
||||
// NB: this is why loadProgress() comes before loadFilePriorities()
|
||||
if (!tor->isDone() && (fieldsToLoad & tr_resume::FilePriorities) != 0)
|
||||
{
|
||||
fields_loaded |= loadFilePriorities(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Dnd) != 0)
|
||||
{
|
||||
fields_loaded |= loadDND(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Speedlimit) != 0)
|
||||
{
|
||||
fields_loaded |= loadSpeedLimits(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Ratiolimit) != 0)
|
||||
{
|
||||
fields_loaded |= loadRatioLimits(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Idlelimit) != 0)
|
||||
{
|
||||
fields_loaded |= loadIdleLimits(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Filenames) != 0)
|
||||
{
|
||||
fields_loaded |= loadFilenames(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Name) != 0)
|
||||
{
|
||||
fields_loaded |= loadName(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & tr_resume::Labels) != 0)
|
||||
{
|
||||
fields_loaded |= loadLabels(&top, tor);
|
||||
}
|
||||
|
||||
/* loading the resume file triggers of a lot of changes,
|
||||
* but none of them needs to trigger a re-saving of the
|
||||
* same resume information... */
|
||||
tor->isDirty = wasDirty;
|
||||
|
||||
tr_variantFree(&top);
|
||||
return fields_loaded;
|
||||
}
|
||||
|
||||
static auto setFromCtor(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor, tr_ctorMode mode)
|
||||
{
|
||||
auto ret = tr_resume::fields_t{};
|
||||
|
||||
if ((fields & tr_resume::Run) != 0)
|
||||
{
|
||||
auto isPaused = bool{};
|
||||
if (tr_ctorGetPaused(ctor, mode, &isPaused))
|
||||
{
|
||||
tor->isRunning = !isPaused;
|
||||
ret |= tr_resume::Run;
|
||||
}
|
||||
}
|
||||
|
||||
if (((fields & tr_resume::MaxPeers) != 0) && tr_ctorGetPeerLimit(ctor, mode, &tor->maxConnectedPeers))
|
||||
{
|
||||
ret |= tr_resume::MaxPeers;
|
||||
}
|
||||
|
||||
if ((fields & tr_resume::DownloadDir) != 0)
|
||||
{
|
||||
char const* path = nullptr;
|
||||
if (tr_ctorGetDownloadDir(ctor, mode, &path) && !tr_str_is_empty(path))
|
||||
{
|
||||
ret |= tr_resume::DownloadDir;
|
||||
tor->download_dir = path;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static auto useManditoryFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor)
|
||||
{
|
||||
return setFromCtor(tor, fields, ctor, TR_FORCE);
|
||||
}
|
||||
|
||||
static auto useFallbackFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor const* ctor)
|
||||
{
|
||||
return setFromCtor(tor, fields, ctor, TR_FALLBACK);
|
||||
}
|
||||
|
||||
namespace tr_resume
|
||||
{
|
||||
|
||||
fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor, bool* did_rename_to_hash_only_name)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
auto ret = fields_t{};
|
||||
|
||||
ret |= useManditoryFields(tor, fields_to_load, ctor);
|
||||
fields_to_load &= ~ret;
|
||||
ret |= loadFromFile(tor, fields_to_load, did_rename_to_hash_only_name);
|
||||
fields_to_load &= ~ret;
|
||||
ret |= useFallbackFields(tor, fields_to_load, ctor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void save(tr_torrent* tor)
|
||||
{
|
||||
if (!tr_isTorrent(tor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto top = tr_variant{};
|
||||
tr_variantInitDict(&top, 50); /* arbitrary "big enough" number */
|
||||
tr_variantDictAddInt(&top, TR_KEY_seeding_time_seconds, tor->secondsSeeding);
|
||||
tr_variantDictAddInt(&top, TR_KEY_downloading_time_seconds, tor->secondsDownloading);
|
||||
|
@ -678,253 +936,4 @@ void tr_torrentSaveResume(tr_torrent* tor)
|
|||
tr_variantFree(&top);
|
||||
}
|
||||
|
||||
static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* did_migrate_filename)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
auto const wasDirty = tor->isDirty;
|
||||
|
||||
auto const migrated = tr_torrent_metainfo::migrateFile(
|
||||
tor->session->resume_dir,
|
||||
tor->name(),
|
||||
tor->infoHashString(),
|
||||
".resume"sv);
|
||||
if (did_migrate_filename != nullptr)
|
||||
{
|
||||
*did_migrate_filename = migrated;
|
||||
}
|
||||
|
||||
auto const filename = tor->resumeFile();
|
||||
auto buf = std::vector<char>{};
|
||||
tr_error* error = nullptr;
|
||||
auto top = tr_variant{};
|
||||
if (!tr_loadFile(buf, filename, &error) ||
|
||||
!tr_variantFromBuf(
|
||||
&top,
|
||||
TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE,
|
||||
{ std::data(buf), std::size(buf) },
|
||||
nullptr,
|
||||
&error))
|
||||
{
|
||||
tr_logAddTorDbg(tor, "Couldn't read \"%s\": %s", filename.c_str(), error->message);
|
||||
tr_error_clear(&error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tr_logAddTorDbg(tor, "Read resume file \"%s\"", filename.c_str());
|
||||
|
||||
auto fieldsLoaded = uint64_t{};
|
||||
auto boolVal = false;
|
||||
auto i = int64_t{};
|
||||
auto sv = std::string_view{};
|
||||
|
||||
if ((fieldsToLoad & TR_FR_CORRUPT) != 0 && tr_variantDictFindInt(&top, TR_KEY_corrupt, &i))
|
||||
{
|
||||
tor->corruptPrev = i;
|
||||
fieldsLoaded |= TR_FR_CORRUPT;
|
||||
}
|
||||
|
||||
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->current_dir == tor->download_dir;
|
||||
tor->download_dir = sv;
|
||||
if (is_current_dir)
|
||||
{
|
||||
tor->current_dir = sv;
|
||||
}
|
||||
|
||||
fieldsLoaded |= TR_FR_DOWNLOAD_DIR;
|
||||
}
|
||||
|
||||
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->current_dir == tor->incomplete_dir;
|
||||
tor->incomplete_dir = sv;
|
||||
if (is_current_dir)
|
||||
{
|
||||
tor->current_dir = sv;
|
||||
}
|
||||
|
||||
fieldsLoaded |= TR_FR_INCOMPLETE_DIR;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_DOWNLOADED) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloaded, &i))
|
||||
{
|
||||
tor->downloadedPrev = i;
|
||||
fieldsLoaded |= TR_FR_DOWNLOADED;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_UPLOADED) != 0 && tr_variantDictFindInt(&top, TR_KEY_uploaded, &i))
|
||||
{
|
||||
tor->uploadedPrev = i;
|
||||
fieldsLoaded |= TR_FR_UPLOADED;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_MAX_PEERS) != 0 && tr_variantDictFindInt(&top, TR_KEY_max_peers, &i))
|
||||
{
|
||||
tor->maxConnectedPeers = i;
|
||||
fieldsLoaded |= TR_FR_MAX_PEERS;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_RUN) != 0 && tr_variantDictFindBool(&top, TR_KEY_paused, &boolVal))
|
||||
{
|
||||
tor->isRunning = !boolVal;
|
||||
fieldsLoaded |= TR_FR_RUN;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_ADDED_DATE) != 0 && tr_variantDictFindInt(&top, TR_KEY_added_date, &i))
|
||||
{
|
||||
tor->addedDate = i;
|
||||
fieldsLoaded |= TR_FR_ADDED_DATE;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_DONE_DATE) != 0 && tr_variantDictFindInt(&top, TR_KEY_done_date, &i))
|
||||
{
|
||||
tor->doneDate = i;
|
||||
fieldsLoaded |= TR_FR_DONE_DATE;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_ACTIVITY_DATE) != 0 && tr_variantDictFindInt(&top, TR_KEY_activity_date, &i))
|
||||
{
|
||||
tor->setDateActive(i);
|
||||
fieldsLoaded |= TR_FR_ACTIVITY_DATE;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_TIME_SEEDING) != 0 && tr_variantDictFindInt(&top, TR_KEY_seeding_time_seconds, &i))
|
||||
{
|
||||
tor->secondsSeeding = i;
|
||||
fieldsLoaded |= TR_FR_TIME_SEEDING;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_TIME_DOWNLOADING) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloading_time_seconds, &i))
|
||||
{
|
||||
tor->secondsDownloading = i;
|
||||
fieldsLoaded |= TR_FR_TIME_DOWNLOADING;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_BANDWIDTH_PRIORITY) != 0 && tr_variantDictFindInt(&top, TR_KEY_bandwidth_priority, &i) &&
|
||||
tr_isPriority(i))
|
||||
{
|
||||
tr_torrentSetPriority(tor, i);
|
||||
fieldsLoaded |= TR_FR_BANDWIDTH_PRIORITY;
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_PEERS) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadPeers(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_PROGRESS) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadProgress(&top, tor);
|
||||
}
|
||||
|
||||
// Only load file priorities if we are actually downloading.
|
||||
// If we're a seed or partial seed, loading it is a waste of time.
|
||||
// NB: this is why loadProgress() comes before loadFilePriorities()
|
||||
if (!tor->isDone() && (fieldsToLoad & TR_FR_FILE_PRIORITIES) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadFilePriorities(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_DND) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadDND(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_SPEEDLIMIT) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadSpeedLimits(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_RATIOLIMIT) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadRatioLimits(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_IDLELIMIT) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadIdleLimits(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_FILENAMES) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadFilenames(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_NAME) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadName(&top, tor);
|
||||
}
|
||||
|
||||
if ((fieldsToLoad & TR_FR_LABELS) != 0)
|
||||
{
|
||||
fieldsLoaded |= loadLabels(&top, tor);
|
||||
}
|
||||
|
||||
/* loading the resume file triggers of a lot of changes,
|
||||
* but none of them needs to trigger a re-saving of the
|
||||
* same resume information... */
|
||||
tor->isDirty = wasDirty;
|
||||
|
||||
tr_variantFree(&top);
|
||||
return fieldsLoaded;
|
||||
}
|
||||
|
||||
static uint64_t setFromCtor(tr_torrent* tor, uint64_t fields, tr_ctor const* ctor, tr_ctorMode mode)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
|
||||
if ((fields & TR_FR_RUN) != 0)
|
||||
{
|
||||
auto isPaused = bool{};
|
||||
if (tr_ctorGetPaused(ctor, mode, &isPaused))
|
||||
{
|
||||
tor->isRunning = !isPaused;
|
||||
ret |= TR_FR_RUN;
|
||||
}
|
||||
}
|
||||
|
||||
if (((fields & TR_FR_MAX_PEERS) != 0) && tr_ctorGetPeerLimit(ctor, mode, &tor->maxConnectedPeers))
|
||||
{
|
||||
ret |= TR_FR_MAX_PEERS;
|
||||
}
|
||||
|
||||
if ((fields & TR_FR_DOWNLOAD_DIR) != 0)
|
||||
{
|
||||
char const* path = nullptr;
|
||||
if (tr_ctorGetDownloadDir(ctor, mode, &path) && !tr_str_is_empty(path))
|
||||
{
|
||||
ret |= TR_FR_DOWNLOAD_DIR;
|
||||
tor->download_dir = path;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint64_t useManditoryFields(tr_torrent* tor, uint64_t fields, tr_ctor const* ctor)
|
||||
{
|
||||
return setFromCtor(tor, fields, ctor, TR_FORCE);
|
||||
}
|
||||
|
||||
static uint64_t useFallbackFields(tr_torrent* tor, uint64_t fields, tr_ctor const* ctor)
|
||||
{
|
||||
return setFromCtor(tor, fields, ctor, TR_FALLBACK);
|
||||
}
|
||||
|
||||
uint64_t tr_torrentLoadResume(tr_torrent* tor, uint64_t fieldsToLoad, tr_ctor const* ctor, bool* didRenameToHashOnlyName)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
uint64_t ret = 0;
|
||||
|
||||
ret |= useManditoryFields(tor, fieldsToLoad, ctor);
|
||||
fieldsToLoad &= ~ret;
|
||||
ret |= loadFromFile(tor, fieldsToLoad, didRenameToHashOnlyName);
|
||||
fieldsToLoad &= ~ret;
|
||||
ret |= useFallbackFields(tor, fieldsToLoad, ctor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace tr_resume
|
||||
|
|
|
@ -9,41 +9,44 @@
|
|||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdint> // uint64_t
|
||||
|
||||
struct tr_ctor;
|
||||
struct tr_torrent;
|
||||
|
||||
enum
|
||||
namespace tr_resume
|
||||
{
|
||||
TR_FR_DOWNLOADED = (1 << 0),
|
||||
TR_FR_UPLOADED = (1 << 1),
|
||||
TR_FR_CORRUPT = (1 << 2),
|
||||
TR_FR_PEERS = (1 << 3),
|
||||
TR_FR_PROGRESS = (1 << 4),
|
||||
TR_FR_DND = (1 << 5),
|
||||
TR_FR_FILE_PRIORITIES = (1 << 6),
|
||||
TR_FR_BANDWIDTH_PRIORITY = (1 << 7),
|
||||
TR_FR_SPEEDLIMIT = (1 << 8),
|
||||
TR_FR_RUN = (1 << 9),
|
||||
TR_FR_DOWNLOAD_DIR = (1 << 10),
|
||||
TR_FR_INCOMPLETE_DIR = (1 << 11),
|
||||
TR_FR_MAX_PEERS = (1 << 12),
|
||||
TR_FR_ADDED_DATE = (1 << 13),
|
||||
TR_FR_DONE_DATE = (1 << 14),
|
||||
TR_FR_ACTIVITY_DATE = (1 << 15),
|
||||
TR_FR_RATIOLIMIT = (1 << 16),
|
||||
TR_FR_IDLELIMIT = (1 << 17),
|
||||
TR_FR_TIME_SEEDING = (1 << 18),
|
||||
TR_FR_TIME_DOWNLOADING = (1 << 19),
|
||||
TR_FR_FILENAMES = (1 << 20),
|
||||
TR_FR_NAME = (1 << 21),
|
||||
TR_FR_LABELS = (1 << 22)
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a bitwise-or'ed set of the loaded resume data
|
||||
*/
|
||||
uint64_t tr_torrentLoadResume(tr_torrent* tor, uint64_t fieldsToLoad, tr_ctor const* ctor, bool* didRenameToHashOnlyName);
|
||||
using fields_t = uint64_t;
|
||||
|
||||
void tr_torrentSaveResume(tr_torrent* tor);
|
||||
auto inline constexpr Downloaded = fields_t{ 1 << 0 };
|
||||
auto inline constexpr Uploaded = fields_t{ 1 << 1 };
|
||||
auto inline constexpr Corrupt = fields_t{ 1 << 2 };
|
||||
auto inline constexpr Peers = fields_t{ 1 << 3 };
|
||||
auto inline constexpr Progress = fields_t{ 1 << 4 };
|
||||
auto inline constexpr Dnd = fields_t{ 1 << 5 };
|
||||
auto inline constexpr FilePriorities = fields_t{ 1 << 6 };
|
||||
auto inline constexpr BandwidthPriority = fields_t{ 1 << 7 };
|
||||
auto inline constexpr Speedlimit = fields_t{ 1 << 8 };
|
||||
auto inline constexpr Run = fields_t{ 1 << 9 };
|
||||
auto inline constexpr DownloadDir = fields_t{ 1 << 10 };
|
||||
auto inline constexpr IncompleteDir = fields_t{ 1 << 11 };
|
||||
auto inline constexpr MaxPeers = fields_t{ 1 << 12 };
|
||||
auto inline constexpr AddedDate = fields_t{ 1 << 13 };
|
||||
auto inline constexpr DoneDate = fields_t{ 1 << 14 };
|
||||
auto inline constexpr ActivityDate = fields_t{ 1 << 15 };
|
||||
auto inline constexpr Ratiolimit = fields_t{ 1 << 16 };
|
||||
auto inline constexpr Idlelimit = fields_t{ 1 << 17 };
|
||||
auto inline constexpr TimeSeeding = fields_t{ 1 << 18 };
|
||||
auto inline constexpr TimeDownloading = fields_t{ 1 << 19 };
|
||||
auto inline constexpr Filenames = fields_t{ 1 << 20 };
|
||||
auto inline constexpr Name = fields_t{ 1 << 21 };
|
||||
auto inline constexpr Labels = fields_t{ 1 << 22 };
|
||||
|
||||
auto inline constexpr All = ~fields_t{ 0 };
|
||||
|
||||
fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor, bool* did_rename_to_hash_only_name);
|
||||
|
||||
void save(tr_torrent* tor);
|
||||
|
||||
} // namespace tr_resume
|
||||
|
|
|
@ -52,10 +52,10 @@ using namespace std::literals;
|
|||
#define dbgmsg(...) tr_logAddDeepNamed("RPC", __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
enum tr_format
|
||||
enum class TrFormat
|
||||
{
|
||||
TR_FORMAT_OBJECT = 0,
|
||||
TR_FORMAT_TABLE
|
||||
Object,
|
||||
Table
|
||||
};
|
||||
|
||||
/***
|
||||
|
@ -832,9 +832,9 @@ static void initField(tr_torrent const* const tor, tr_stat const* const st, tr_v
|
|||
}
|
||||
}
|
||||
|
||||
static void addTorrentInfo(tr_torrent* tor, tr_format format, tr_variant* entry, tr_quark const* fields, size_t fieldCount)
|
||||
static void addTorrentInfo(tr_torrent* tor, TrFormat format, tr_variant* entry, tr_quark const* fields, size_t fieldCount)
|
||||
{
|
||||
if (format == TR_FORMAT_TABLE)
|
||||
if (format == TrFormat::Table)
|
||||
{
|
||||
tr_variantInitList(entry, fieldCount);
|
||||
}
|
||||
|
@ -849,7 +849,7 @@ static void addTorrentInfo(tr_torrent* tor, tr_format format, tr_variant* entry,
|
|||
|
||||
for (size_t i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
tr_variant* child = format == TR_FORMAT_TABLE ? tr_variantListAdd(entry) : tr_variantDictAdd(entry, fields[i]);
|
||||
tr_variant* child = format == TrFormat::Table ? tr_variantListAdd(entry) : tr_variantDictAdd(entry, fields[i]);
|
||||
|
||||
initField(tor, st, child, fields[i]);
|
||||
}
|
||||
|
@ -862,8 +862,8 @@ static char const* torrentGet(tr_session* session, tr_variant* args_in, tr_varia
|
|||
tr_variant* const list = tr_variantDictAddList(args_out, TR_KEY_torrents, std::size(torrents) + 1);
|
||||
|
||||
auto sv = std::string_view{};
|
||||
tr_format const format = tr_variantDictFindStrView(args_in, TR_KEY_format, &sv) && sv == "table"sv ? TR_FORMAT_TABLE :
|
||||
TR_FORMAT_OBJECT;
|
||||
auto const format = tr_variantDictFindStrView(args_in, TR_KEY_format, &sv) && sv == "table"sv ? TrFormat::Table :
|
||||
TrFormat::Object;
|
||||
|
||||
if (tr_variantDictFindStrView(args_in, TR_KEY_ids, &sv) && sv == "recently-active"sv)
|
||||
{
|
||||
|
@ -909,7 +909,7 @@ static char const* torrentGet(tr_session* session, tr_variant* args_in, tr_varia
|
|||
keys[keyCount++] = *key;
|
||||
}
|
||||
|
||||
if (format == TR_FORMAT_TABLE)
|
||||
if (format == TrFormat::Table)
|
||||
{
|
||||
/* first entry is an array of property names */
|
||||
tr_variant* names = tr_variantListAddList(list, keyCount);
|
||||
|
@ -1496,7 +1496,7 @@ static void addTorrentImpl(struct tr_rpc_idle_data* data, tr_ctor* ctor)
|
|||
TR_KEY_hashString,
|
||||
};
|
||||
|
||||
addTorrentInfo(tor, TR_FORMAT_OBJECT, tr_variantDictAdd(data->args_out, key), fields, TR_N_ELEMENTS(fields));
|
||||
addTorrentInfo(tor, TrFormat::Object, tr_variantDictAdd(data->args_out, key), fields, TR_N_ELEMENTS(fields));
|
||||
|
||||
if (result == nullptr)
|
||||
{
|
||||
|
|
|
@ -672,13 +672,13 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
|||
tor->addedDate = now; // this is a default that will be overwritten by the resume file
|
||||
tor->anyDate = now;
|
||||
|
||||
// tr_torrentLoadResume() calls a lot of tr_torrentSetFoo() methods
|
||||
// tr_resume::load() calls a lot of tr_torrentSetFoo() methods
|
||||
// that set things as dirty, but... these settings being loaded are
|
||||
// the same ones that would be saved back again, so don't let them
|
||||
// affect the 'is dirty' flag.
|
||||
auto const was_dirty = tor->isDirty;
|
||||
bool resume_file_was_migrated = false;
|
||||
auto const loaded = tr_torrentLoadResume(tor, ~(uint64_t)0, ctor, &resume_file_was_migrated);
|
||||
auto const loaded = tr_resume::load(tor, tr_resume::All, ctor, &resume_file_was_migrated);
|
||||
tor->isDirty = was_dirty;
|
||||
|
||||
if (resume_file_was_migrated)
|
||||
|
@ -696,7 +696,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
|||
bool const doStart = tor->isRunning;
|
||||
tor->isRunning = false;
|
||||
|
||||
if ((loaded & TR_FR_SPEEDLIMIT) == 0)
|
||||
if ((loaded & tr_resume::Speedlimit) == 0)
|
||||
{
|
||||
tr_torrentUseSpeedLimit(tor, TR_UP, false);
|
||||
tor->setSpeedLimitBps(TR_UP, tr_sessionGetSpeedLimit_Bps(tor->session, TR_UP));
|
||||
|
@ -705,13 +705,13 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
|||
tr_torrentUseSessionLimits(tor, true);
|
||||
}
|
||||
|
||||
if ((loaded & TR_FR_RATIOLIMIT) == 0)
|
||||
if ((loaded & tr_resume::Ratiolimit) == 0)
|
||||
{
|
||||
tr_torrentSetRatioMode(tor, TR_RATIOLIMIT_GLOBAL);
|
||||
tr_torrentSetRatioLimit(tor, tr_sessionGetRatioLimit(tor->session));
|
||||
}
|
||||
|
||||
if ((loaded & TR_FR_IDLELIMIT) == 0)
|
||||
if ((loaded & tr_resume::Idlelimit) == 0)
|
||||
{
|
||||
tr_torrentSetIdleMode(tor, TR_IDLELIMIT_GLOBAL);
|
||||
tr_torrentSetIdleLimit(tor, tr_sessionGetIdleLimit(tor->session));
|
||||
|
@ -1471,7 +1471,7 @@ void tr_torrentSave(tr_torrent* tor)
|
|||
if (tor->isDirty)
|
||||
{
|
||||
tor->isDirty = false;
|
||||
tr_torrentSaveResume(tor);
|
||||
tr_resume::save(tor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -587,7 +587,7 @@ NSMutableSet* creatorWindowControllerSet = nil;
|
|||
NSAlert* alert;
|
||||
switch (fInfo->result)
|
||||
{
|
||||
case TR_MAKEMETA_OK:
|
||||
case TrMakemetaResult::OK:
|
||||
if (fOpenWhenCreated)
|
||||
{
|
||||
NSDictionary* dict = @{ @"File" : fLocation.path, @"Path" : fPath.URLByDeletingLastPathComponent.path };
|
||||
|
@ -597,7 +597,7 @@ NSMutableSet* creatorWindowControllerSet = nil;
|
|||
[self.window close];
|
||||
break;
|
||||
|
||||
case TR_MAKEMETA_CANCELLED:
|
||||
case TrMakemetaResult::CANCELLED:
|
||||
[self.window close];
|
||||
break;
|
||||
|
||||
|
@ -608,14 +608,14 @@ NSMutableSet* creatorWindowControllerSet = nil;
|
|||
fLocation.lastPathComponent];
|
||||
alert.alertStyle = NSAlertStyleWarning;
|
||||
|
||||
if (fInfo->result == TR_MAKEMETA_IO_READ)
|
||||
if (fInfo->result == TrMakemetaResult::ERR_IO_READ)
|
||||
{
|
||||
alert.informativeText = [NSString
|
||||
stringWithFormat:NSLocalizedString(@"Could not read \"%s\": %s.", "Create torrent -> failed -> warning"),
|
||||
fInfo->errfile,
|
||||
strerror(fInfo->my_errno)];
|
||||
}
|
||||
else if (fInfo->result == TR_MAKEMETA_IO_WRITE)
|
||||
else if (fInfo->result == TrMakemetaResult::ERR_IO_WRITE)
|
||||
{
|
||||
alert.informativeText = [NSString
|
||||
stringWithFormat:NSLocalizedString(@"Could not write \"%s\": %s.", "Create torrent -> failed -> warning"),
|
||||
|
|
|
@ -59,12 +59,9 @@ char const* getUsage()
|
|||
" transmission [OPTIONS...] [torrent files]";
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
STATS_REFRESH_INTERVAL_MSEC = 3000,
|
||||
SESSION_REFRESH_INTERVAL_MSEC = 3000,
|
||||
MODEL_REFRESH_INTERVAL_MSEC = 3000
|
||||
};
|
||||
auto constexpr StatsRefreshIntervalMsec = int{ 3000 };
|
||||
auto constexpr SessionRefreshIntervalMsec = int{ 3000 };
|
||||
auto constexpr ModelRefreshIntervalMsec = int{ 3000 };
|
||||
|
||||
bool loadTranslation(QTranslator& translator, QString const& name, QLocale const& locale, QStringList const& search_directories)
|
||||
{
|
||||
|
@ -299,19 +296,19 @@ Application::Application(int& argc, char** argv)
|
|||
QTimer* timer = &model_timer_;
|
||||
connect(timer, &QTimer::timeout, this, &Application::refreshTorrents);
|
||||
timer->setSingleShot(false);
|
||||
timer->setInterval(MODEL_REFRESH_INTERVAL_MSEC);
|
||||
timer->setInterval(ModelRefreshIntervalMsec);
|
||||
timer->start();
|
||||
|
||||
timer = &stats_timer_;
|
||||
connect(timer, &QTimer::timeout, session_.get(), &Session::refreshSessionStats);
|
||||
timer->setSingleShot(false);
|
||||
timer->setInterval(STATS_REFRESH_INTERVAL_MSEC);
|
||||
timer->setInterval(StatsRefreshIntervalMsec);
|
||||
timer->start();
|
||||
|
||||
timer = &session_timer_;
|
||||
connect(timer, &QTimer::timeout, session_.get(), &Session::refreshSessionInfo);
|
||||
timer->setSingleShot(false);
|
||||
timer->setInterval(SESSION_REFRESH_INTERVAL_MSEC);
|
||||
timer->setInterval(SessionRefreshIntervalMsec);
|
||||
timer->start();
|
||||
|
||||
maybeUpdateBlocklist();
|
||||
|
|
|
@ -281,13 +281,13 @@ QString FileTreeItem::priorityString() const
|
|||
|
||||
switch (i)
|
||||
{
|
||||
case LOW:
|
||||
case Low:
|
||||
return tr("Low");
|
||||
|
||||
case HIGH:
|
||||
case High:
|
||||
return tr("High");
|
||||
|
||||
case NORMAL:
|
||||
case Normal:
|
||||
return tr("Normal");
|
||||
|
||||
default:
|
||||
|
@ -304,15 +304,15 @@ int FileTreeItem::priority() const
|
|||
switch (priority_)
|
||||
{
|
||||
case TR_PRI_LOW:
|
||||
i |= LOW;
|
||||
i |= Low;
|
||||
break;
|
||||
|
||||
case TR_PRI_HIGH:
|
||||
i |= HIGH;
|
||||
i |= High;
|
||||
break;
|
||||
|
||||
default:
|
||||
i |= NORMAL;
|
||||
i |= Normal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,9 @@ class FileTreeItem
|
|||
TR_DISABLE_COPY_MOVE(FileTreeItem)
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
LOW = (1 << 0),
|
||||
NORMAL = (1 << 1),
|
||||
HIGH = (1 << 2)
|
||||
};
|
||||
static auto constexpr Low = int{ 1 << 0 };
|
||||
static auto constexpr Normal = int{ 1 << 1 };
|
||||
static auto constexpr High = int{ 1 << 2 };
|
||||
|
||||
FileTreeItem(QString const& name = QString(), int file_index = -1, uint64_t size = 0)
|
||||
: name_(name)
|
||||
|
|
|
@ -491,11 +491,11 @@ void FileTreeModel::twiddlePriority(QModelIndexList const& indices)
|
|||
int priority = item->priority();
|
||||
|
||||
// ... -> normal -> high -> low -> normal -> ...; mixed -> normal
|
||||
if (priority == FileTreeItem::NORMAL)
|
||||
if (priority == FileTreeItem::Normal)
|
||||
{
|
||||
priority = TR_PRI_HIGH;
|
||||
}
|
||||
else if (priority == FileTreeItem::HIGH)
|
||||
else if (priority == FileTreeItem::High)
|
||||
{
|
||||
priority = TR_PRI_LOW;
|
||||
}
|
||||
|
|
|
@ -91,31 +91,31 @@ void MakeProgressDialog::onProgress()
|
|||
ui_.progressBar->setValue(static_cast<int>((100.0 * b.pieceIndex) / denom));
|
||||
|
||||
// progress label
|
||||
QString const top = QString::fromUtf8(b.top);
|
||||
QString const base(QFileInfo(top).completeBaseName());
|
||||
auto const top = QString::fromUtf8(b.top);
|
||||
auto const base = QFileInfo(top).completeBaseName();
|
||||
QString str;
|
||||
|
||||
if (!b.isDone)
|
||||
{
|
||||
str = tr("Creating \"%1\"").arg(base);
|
||||
}
|
||||
else if (b.result == TR_MAKEMETA_OK)
|
||||
else if (b.result == TrMakemetaResult::OK)
|
||||
{
|
||||
str = tr("Created \"%1\"!").arg(base);
|
||||
}
|
||||
else if (b.result == TR_MAKEMETA_URL)
|
||||
{
|
||||
str = tr("Error: invalid announce URL \"%1\"").arg(QString::fromUtf8(b.errfile));
|
||||
}
|
||||
else if (b.result == TR_MAKEMETA_CANCELLED)
|
||||
else if (b.result == TrMakemetaResult::CANCELLED)
|
||||
{
|
||||
str = tr("Cancelled");
|
||||
}
|
||||
else if (b.result == TR_MAKEMETA_IO_READ)
|
||||
else if (b.result == TrMakemetaResult::ERR_URL)
|
||||
{
|
||||
str = tr("Error: invalid announce URL \"%1\"").arg(QString::fromUtf8(b.errfile));
|
||||
}
|
||||
else if (b.result == TrMakemetaResult::ERR_IO_READ)
|
||||
{
|
||||
str = tr("Error reading \"%1\": %2").arg(QString::fromUtf8(b.errfile)).arg(QString::fromUtf8(tr_strerror(b.my_errno)));
|
||||
}
|
||||
else if (b.result == TR_MAKEMETA_IO_WRITE)
|
||||
else if (b.result == TrMakemetaResult::ERR_IO_WRITE)
|
||||
{
|
||||
str = tr("Error writing \"%1\": %2").arg(QString::fromUtf8(b.errfile)).arg(QString::fromUtf8(tr_strerror(b.my_errno)));
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ void MakeProgressDialog::onProgress()
|
|||
// buttons
|
||||
ui_.dialogButtons->button(QDialogButtonBox::Abort)->setEnabled(!b.isDone);
|
||||
ui_.dialogButtons->button(QDialogButtonBox::Ok)->setEnabled(b.isDone);
|
||||
ui_.dialogButtons->button(QDialogButtonBox::Open)->setEnabled(b.isDone && b.result == TR_MAKEMETA_OK);
|
||||
ui_.dialogButtons->button(QDialogButtonBox::Open)->setEnabled(b.isDone && b.result == TrMakemetaResult::OK);
|
||||
}
|
||||
|
||||
#include "MakeDialog.moc"
|
||||
|
|
|
@ -139,7 +139,6 @@ protected:
|
|||
|
||||
TEST_F(RenameTest, singleFilenameTorrent)
|
||||
{
|
||||
uint64_t loaded;
|
||||
static auto constexpr TotalSize = size_t{ 14 };
|
||||
|
||||
// this is a single-file torrent whose file is hello-world.txt, holding the string "hello, world!"
|
||||
|
@ -207,11 +206,11 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
EXPECT_TRUE(testFileExistsAndConsistsOfThisString(tor, 0, "hello, world!\n")); // confirm the contents are right
|
||||
|
||||
// (while it's renamed: confirm that the .resume file remembers the changes)
|
||||
tr_torrentSaveResume(tor);
|
||||
tr_resume::save(tor);
|
||||
sync();
|
||||
loaded = tr_torrentLoadResume(tor, ~0ULL, ctor, nullptr);
|
||||
auto const loaded = tr_resume::load(tor, tr_resume::All, ctor, nullptr);
|
||||
EXPECT_STREQ("foobar", tr_torrentName(tor));
|
||||
EXPECT_NE(decltype(loaded){ 0 }, (loaded & TR_FR_NAME));
|
||||
EXPECT_NE(decltype(loaded){ 0 }, (loaded & tr_resume::Name));
|
||||
|
||||
/***
|
||||
**** ...and rename it back again
|
||||
|
@ -318,11 +317,11 @@ TEST_F(RenameTest, multifileTorrent)
|
|||
EXPECT_TRUE(testFileExistsAndConsistsOfThisString(tor, 2, expected_contents[2]));
|
||||
|
||||
// (while the branch is renamed: confirm that the .resume file remembers the changes)
|
||||
tr_torrentSaveResume(tor);
|
||||
tr_resume::save(tor);
|
||||
// this is a bit dodgy code-wise, but let's make sure the .resume file got the name
|
||||
tor->setFileSubpath(1, "gabba gabba hey"sv);
|
||||
auto const loaded = tr_torrentLoadResume(tor, ~0ULL, ctor, nullptr);
|
||||
EXPECT_NE(decltype(loaded){ 0 }, (loaded & TR_FR_FILENAMES));
|
||||
auto const loaded = tr_resume::load(tor, tr_resume::All, ctor, nullptr);
|
||||
EXPECT_NE(decltype(loaded){ 0 }, (loaded & tr_resume::Filenames));
|
||||
EXPECT_EQ(expected_files[0], tr_torrentFile(tor, 0).name);
|
||||
EXPECT_STREQ("Felidae/Felinae/Felis/placeholder/Kyphi", tr_torrentFile(tor, 1).name);
|
||||
EXPECT_STREQ("Felidae/Felinae/Felis/placeholder/Saffron", tr_torrentFile(tor, 2).name);
|
||||
|
|
|
@ -243,23 +243,23 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
switch (b->result)
|
||||
{
|
||||
case TR_MAKEMETA_OK:
|
||||
case TrMakemetaResult::OK:
|
||||
printf("done!");
|
||||
break;
|
||||
|
||||
case TR_MAKEMETA_URL:
|
||||
case TrMakemetaResult::ERR_URL:
|
||||
printf("bad announce URL: \"%s\"", b->errfile);
|
||||
break;
|
||||
|
||||
case TR_MAKEMETA_IO_READ:
|
||||
case TrMakemetaResult::ERR_IO_READ:
|
||||
printf("error reading \"%s\": %s", b->errfile, tr_strerror(b->my_errno));
|
||||
break;
|
||||
|
||||
case TR_MAKEMETA_IO_WRITE:
|
||||
case TrMakemetaResult::ERR_IO_WRITE:
|
||||
printf("error writing \"%s\": %s", b->errfile, tr_strerror(b->my_errno));
|
||||
break;
|
||||
|
||||
case TR_MAKEMETA_CANCELLED:
|
||||
case TrMakemetaResult::CANCELLED:
|
||||
printf("cancelled");
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue