diff --git a/libtransmission/torrent-magnet.cc b/libtransmission/torrent-magnet.cc index 8efc1317c..f8fb4999c 100644 --- a/libtransmission/torrent-magnet.cc +++ b/libtransmission/torrent-magnet.cc @@ -27,25 +27,6 @@ #include "libtransmission/utils.h" #include "libtransmission/variant.h" -namespace -{ -struct metadata_node -{ - time_t requested_at = 0U; - int piece = 0; -}; -} // namespace - -struct tr_incomplete_metadata -{ - std::vector metadata; - - /** sorted from least to most recently requested */ - std::deque pieces_needed; - - int piece_count = 0; -}; - namespace { // don't ask for the same metadata piece more than this often @@ -53,7 +34,7 @@ auto constexpr MinRepeatIntervalSecs = int{ 3 }; auto create_all_needed(int n_pieces) { - auto ret = std::deque{}; + auto ret = std::deque{}; ret.resize(n_pieces); @@ -79,7 +60,7 @@ bool tr_torrentSetMetadataSizeHint(tr_torrent* tor, int64_t size) return false; } - if (tor->incompleteMetadata != nullptr) + if (tor->incomplete_metadata) { return false; } @@ -91,24 +72,18 @@ bool tr_torrentSetMetadataSizeHint(tr_torrent* tor, int64_t size) return false; } - auto* const m = new tr_incomplete_metadata{}; + auto m = tr_incomplete_metadata{}; - if (m == nullptr) + m.piece_count = n; + m.metadata.resize(size); + m.pieces_needed = create_all_needed(n); + + if (std::empty(m.metadata) || std::empty(m.pieces_needed)) { return false; } - m->piece_count = n; - m->metadata.resize(size); - m->pieces_needed = create_all_needed(n); - - if (std::empty(m->metadata) || std::empty(m->pieces_needed)) - { - delete m; - return false; - } - - tor->incompleteMetadata = m; + tor->incomplete_metadata = std::move(m); return true; } @@ -166,11 +141,7 @@ bool tr_torrentUseMetainfoFromFile( // tor should keep this metainfo tor->set_metainfo(*metainfo); - if (tor->incompleteMetadata != nullptr) - { - delete tor->incompleteMetadata; - tor->incompleteMetadata = nullptr; - } + tor->incomplete_metadata.reset(); return true; } @@ -181,10 +152,10 @@ namespace { namespace set_metadata_piece_helpers { -[[nodiscard]] constexpr size_t get_piece_length(struct tr_incomplete_metadata const* m, int piece) +[[nodiscard]] constexpr size_t get_piece_length(tr_incomplete_metadata const& m, int piece) { - return piece + 1 == m->piece_count ? // last piece - std::size(m->metadata) - (piece * METADATA_PIECE_SIZE) : + return piece + 1 == m.piece_count ? // last piece + std::size(m.metadata) - (piece * METADATA_PIECE_SIZE) : METADATA_PIECE_SIZE; } @@ -246,8 +217,10 @@ void build_metainfo_except_info_dict(tr_torrent_metainfo const& tm, tr_variant* } } -bool use_new_metainfo(tr_torrent* tor, tr_incomplete_metadata const* m, tr_error** error) +bool use_new_metainfo(tr_torrent* tor, tr_error** error) { + auto const& m = tor->incomplete_metadata; + // test the info_dict checksum if (tr_sha1::digest(m->metadata) != tor->info_hash()) { @@ -291,17 +264,17 @@ bool use_new_metainfo(tr_torrent* tor, tr_incomplete_metadata const* m, tr_error return true; } -void on_have_all_metainfo(tr_torrent* tor, tr_incomplete_metadata* m) +void on_have_all_metainfo(tr_torrent* tor) { tr_error* error = nullptr; - if (use_new_metainfo(tor, m, &error)) + auto& m = tor->incomplete_metadata; + if (use_new_metainfo(tor, &error)) { - delete tor->incompleteMetadata; - tor->incompleteMetadata = nullptr; + m.reset(); } else /* drat. */ { - int const n = m->piece_count; + auto const n = m->piece_count; m->pieces_needed = create_all_needed(n); @@ -327,10 +300,10 @@ void tr_torrentMagnetDoIdleWork(tr_torrent* const tor) TR_ASSERT(tr_isTorrent(tor)); - if (auto* const m = tor->incompleteMetadata; m != nullptr && std::empty(m->pieces_needed)) + if (auto const& m = tor->incomplete_metadata; m && std::empty(m->pieces_needed)) { tr_logAddDebugTor(tor, fmt::format("we now have all the metainfo!")); - on_have_all_metainfo(tor, m); + on_have_all_metainfo(tor); } } @@ -344,8 +317,8 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, si tr_logAddDebugTor(tor, fmt::format("got metadata piece {} of {} bytes", piece, len)); // are we set up to download metadata? - tr_incomplete_metadata* const m = tor->incompleteMetadata; - if (m == nullptr) + auto& m = tor->incomplete_metadata; + if (!m) { return; } @@ -357,7 +330,7 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, si } // sanity test: is `len` the right size? - if (get_piece_length(m, piece) != len) + if (get_piece_length(*m, piece) != len) { return; } @@ -386,8 +359,8 @@ std::optional tr_torrentGetNextMetadataRequest(tr_torrent* tor, time_t now) { TR_ASSERT(tr_isTorrent(tor)); - struct tr_incomplete_metadata* m = tor->incompleteMetadata; - if (m == nullptr) + auto& m = tor->incomplete_metadata; + if (!m) { return {}; } @@ -413,8 +386,9 @@ double tr_torrentGetMetadataPercent(tr_torrent const* tor) return 1.0; } - auto const* const m = tor->incompleteMetadata; - return m == nullptr || m->piece_count == 0 ? 0.0 : (m->piece_count - std::size(m->pieces_needed)) / (double)m->piece_count; + auto const& m = tor->incomplete_metadata; + auto const& n = m->piece_count; + return !m || n == 0 ? 0.0 : (n - std::size(m->pieces_needed)) / static_cast(n); } std::string tr_torrentGetMagnetLink(tr_torrent const* tor) diff --git a/libtransmission/torrent-magnet.h b/libtransmission/torrent-magnet.h index e7abb116e..3841d38c0 100644 --- a/libtransmission/torrent-magnet.h +++ b/libtransmission/torrent-magnet.h @@ -12,6 +12,7 @@ #include // size_t #include // int64_t #include // time_t +#include #include #include @@ -26,6 +27,22 @@ inline constexpr int METADATA_PIECE_SIZE = 1024 * 16; using tr_metadata_piece = small::max_size_vector; +struct tr_incomplete_metadata +{ + struct metadata_node + { + time_t requested_at = 0U; + int piece = 0; + }; + + std::vector metadata; + + /** sorted from least to most recently requested */ + std::deque pieces_needed; + + int piece_count = 0; +}; + bool tr_torrentGetMetadataPiece(tr_torrent const* tor, int piece, tr_metadata_piece& setme); void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, size_t len); diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index 89a77658e..beab38a57 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -17,21 +17,22 @@ #include #include -#include "transmission.h" +#include "libtransmission/transmission.h" -#include "announce-list.h" -#include "bandwidth.h" -#include "bitfield.h" -#include "block-info.h" -#include "completion.h" -#include "crypto-utils.h" -#include "file-piece-map.h" -#include "interned-string.h" -#include "observable.h" -#include "log.h" -#include "session.h" -#include "torrent-metainfo.h" -#include "tr-macros.h" +#include "libtransmission/announce-list.h" +#include "libtransmission/bandwidth.h" +#include "libtransmission/bitfield.h" +#include "libtransmission/block-info.h" +#include "libtransmission/completion.h" +#include "libtransmission/crypto-utils.h" +#include "libtransmission/file-piece-map.h" +#include "libtransmission/interned-string.h" +#include "libtransmission/observable.h" +#include "libtransmission/log.h" +#include "libtransmission/session.h" +#include "libtransmission/torrent-magnet.h" +#include "libtransmission/torrent-metainfo.h" +#include "libtransmission/tr-macros.h" class tr_swarm; struct tr_error; @@ -863,7 +864,7 @@ public: /* Used when the torrent has been created with a magnet link * and we're in the process of downloading the metainfo from * other peers */ - struct tr_incomplete_metadata* incompleteMetadata = nullptr; + std::optional incomplete_metadata; time_t lpdAnnounceAt = 0;