diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index a6bf947f8..0e7c8adbb 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -30,6 +30,7 @@ #include "sessionimpl.h" #include +#include #include #include #include @@ -315,6 +316,44 @@ namespace break; } } + +#ifdef QBT_USES_LIBTORRENT2 + template + concept HasInfoHashMember = requires (T t) { { t.info_hashes } -> std::convertible_to; }; + + template + concept HasInfoHashMemberFn = requires (T t) { { t.info_hashes() } -> std::convertible_to; }; + + template + InfoHash getInfoHash(const T &t) { return t.info_hashes; } + + template + InfoHash getInfoHash(const T &t) { return t.info_hashes(); } + + InfoHash getInfoHash(const lt::add_torrent_params &addTorrentParams) + { + const bool hasMetadata = (addTorrentParams.ti && addTorrentParams.ti->is_valid()); + return hasMetadata ? getInfoHash(*addTorrentParams.ti) : InfoHash(addTorrentParams.info_hashes); + } + #else + template + concept HasInfoHashMember = requires (T t) { { t.info_hash } -> std::convertible_to; }; + + template + concept HasInfoHashMemberFn = requires (T t) { { t.info_hash() } -> std::convertible_to; }; + + template + InfoHash getInfoHash(const T &t) { return t.info_hash; } + + template + InfoHash getInfoHash(const T &t) { return t.info_hash(); } + + InfoHash getInfoHash(const lt::add_torrent_params &addTorrentParams) + { + const bool hasMetadata = (addTorrentParams.ti && addTorrentParams.ti->is_valid()); + return hasMetadata ? getInfoHash(*addTorrentParams.ti) : InfoHash(addTorrentParams.info_hash); + } + #endif } struct BitTorrent::SessionImpl::ResumeSessionContext final : public QObject @@ -1443,10 +1482,8 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context) LoadTorrentParams resumeData = *loadResumeDataResult; bool needStore = false; + const InfoHash infoHash = getInfoHash(resumeData.ltAddTorrentParams); #ifdef QBT_USES_LIBTORRENT2 - const InfoHash infoHash {(resumeData.ltAddTorrentParams.ti - ? resumeData.ltAddTorrentParams.ti->info_hashes() - : resumeData.ltAddTorrentParams.info_hashes)}; const bool isHybrid = infoHash.isHybrid(); const auto torrentIDv2 = TorrentID::fromInfoHash(infoHash); const auto torrentIDv1 = TorrentID::fromSHA1Hash(infoHash.v1()); @@ -1494,9 +1531,6 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context) return; } #else - const lt::sha1_hash infoHash = (resumeData.ltAddTorrentParams.ti - ? resumeData.ltAddTorrentParams.ti->info_hash() - : resumeData.ltAddTorrentParams.info_hash); if (torrentID != TorrentID::fromInfoHash(infoHash)) { LogMsg(tr("Failed to resume torrent: inconsistent torrent ID is detected. Torrent: \"%1\"") @@ -2398,7 +2432,7 @@ Torrent *SessionImpl::getTorrent(const TorrentID &id) const Torrent *SessionImpl::findTorrent(const InfoHash &infoHash) const { const auto id = TorrentID::fromInfoHash(infoHash); - if (Torrent *torrent = m_torrents.value(id); torrent) + if (Torrent *torrent = m_torrents.value(id)) return torrent; if (!infoHash.isHybrid()) @@ -2515,7 +2549,7 @@ bool SessionImpl::cancelDownloadMetadata(const TorrentID &id) return true; #ifdef QBT_USES_LIBTORRENT2 - const InfoHash infoHash {nativeHandle.info_hashes()}; + const InfoHash infoHash = getInfoHash(nativeHandle); if (infoHash.isHybrid()) { // if magnet link was hybrid initially then it is indexed also by v1 info hash @@ -5417,13 +5451,8 @@ bool SessionImpl::addMoveTorrentStorageJob(TorrentImpl *torrent, const Path &new void SessionImpl::moveTorrentStorage(const MoveStorageJob &job) const { -#ifdef QBT_USES_LIBTORRENT2 - const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hashes()); -#else - const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hash()); -#endif - const TorrentImpl *torrent = m_torrents.value(id); - const QString torrentName = (torrent ? torrent->name() : id.toString()); + const TorrentImpl *torrent = getTorrent(job.torrentHandle); + const QString torrentName = (torrent ? torrent->name() : getInfoHash(job.torrentHandle).toTorrentID().toString()); LogMsg(tr("Start moving torrent. Torrent: \"%1\". Destination: \"%2\"").arg(torrentName, job.path.toString())); job.torrentHandle.move_storage(job.path.toString().toStdString(), toNative(job.mode)); @@ -5443,7 +5472,7 @@ void SessionImpl::handleMoveTorrentStorageJobFinished(const Path &newPath) const bool torrentHasOutstandingJob = (iter != m_moveStorageQueue.cend()); - TorrentImpl *torrent = m_torrents.value(finishedJob.torrentHandle.info_hash()); + TorrentImpl *torrent = getTorrent(finishedJob.torrentHandle); if (torrent) { torrent->handleMoveStorageJobFinished(newPath, finishedJob.context, torrentHasOutstandingJob); @@ -5451,8 +5480,9 @@ void SessionImpl::handleMoveTorrentStorageJobFinished(const Path &newPath) else if (!torrentHasOutstandingJob) { // Last job is completed for torrent that being removing, so actually remove it - const lt::torrent_handle nativeHandle {finishedJob.torrentHandle}; - const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()]; + const lt::torrent_handle nativeHandle = finishedJob.torrentHandle; + const TorrentID torrentID = getInfoHash(nativeHandle).toTorrentID(); + const RemovingTorrentData &removingTorrentData = m_removingTorrents[torrentID]; if (removingTorrentData.removeOption == TorrentRemoveOption::KeepContent) m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile); } @@ -5749,15 +5779,10 @@ void SessionImpl::handleAddTorrentAlert(const lt::add_torrent_alert *alert) LogMsg(tr("Failed to load torrent. Reason: \"%1\"").arg(msg), Log::WARNING); emit loadTorrentFailed(msg); - const lt::add_torrent_params ¶ms = alert->params; - const bool hasMetadata = (params.ti && params.ti->is_valid()); - + const InfoHash infoHash = getInfoHash(alert->params); #ifdef QBT_USES_LIBTORRENT2 - const InfoHash infoHash {(hasMetadata ? params.ti->info_hashes() : params.info_hashes)}; if (infoHash.isHybrid()) m_hybridTorrentsByAltID.remove(TorrentID::fromSHA1Hash(infoHash.v1())); -#else - const InfoHash infoHash {(hasMetadata ? params.ti->info_hash() : params.info_hash)}; #endif if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(TorrentID::fromInfoHash(infoHash)) ; loadingTorrentsIter != m_loadingTorrents.cend()) @@ -5782,11 +5807,7 @@ void SessionImpl::handleAddTorrentAlert(const lt::add_torrent_alert *alert) return; } -#ifdef QBT_USES_LIBTORRENT2 - const InfoHash infoHash {alert->handle.info_hashes()}; -#else - const InfoHash infoHash {alert->handle.info_hash()}; -#endif + const InfoHash infoHash = getInfoHash(alert->handle); const auto torrentID = TorrentID::fromInfoHash(infoHash); if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(torrentID) @@ -5930,12 +5951,11 @@ void SessionImpl::dispatchTorrentAlert(const lt::torrent_alert *alert) --m_numResumeData; } - const TorrentID torrentID {alert->handle.info_hash()}; - TorrentImpl *torrent = m_torrents.value(torrentID); + TorrentImpl *torrent = getTorrent(alert->handle); #ifdef QBT_USES_LIBTORRENT2 if (!torrent && (alert->type() == lt::metadata_received_alert::alert_type)) { - const InfoHash infoHash {alert->handle.info_hashes()}; + const InfoHash infoHash = getInfoHash(alert->handle); if (infoHash.isHybrid()) torrent = m_torrents.value(TorrentID::fromSHA1Hash(infoHash.v1())); } @@ -6000,6 +6020,11 @@ TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle, return torrent; } +TorrentImpl *SessionImpl::getTorrent(const lt::torrent_handle &nativeHandle) const +{ + return m_torrents.value(getInfoHash(nativeHandle).toTorrentID()); +} + void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert */*alert*/) { // We cannot consider `torrent_removed_alert` as a starting point for removing content, @@ -6009,34 +6034,19 @@ void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert */*a void SessionImpl::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *alert) { -#ifdef QBT_USES_LIBTORRENT2 - const auto torrentID = TorrentID::fromInfoHash(alert->info_hashes); -#else - const auto torrentID = TorrentID::fromInfoHash(alert->info_hash); -#endif - handleRemovedTorrent(torrentID); + handleRemovedTorrent(getInfoHash(*alert).toTorrentID()); } void SessionImpl::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *alert) { -#ifdef QBT_USES_LIBTORRENT2 - const auto torrentID = TorrentID::fromInfoHash(alert->info_hashes); -#else - const auto torrentID = TorrentID::fromInfoHash(alert->info_hash); -#endif + const TorrentID torrentID = getInfoHash(*alert).toTorrentID(); const auto errorMessage = alert->error ? Utils::String::fromLocal8Bit(alert->error.message()) : QString(); handleRemovedTorrent(torrentID, errorMessage); } void SessionImpl::handleTorrentNeedCertAlert(const lt::torrent_need_cert_alert *alert) { -#ifdef QBT_USES_LIBTORRENT2 - const InfoHash infoHash {alert->handle.info_hashes()}; -#else - const InfoHash infoHash {alert->handle.info_hash()}; -#endif - const auto torrentID = TorrentID::fromInfoHash(infoHash); - + const TorrentID torrentID = getInfoHash(alert->handle).toTorrentID(); TorrentImpl *const torrent = m_torrents.value(torrentID); if (!torrent) [[unlikely]] return; @@ -6050,7 +6060,8 @@ void SessionImpl::handleTorrentNeedCertAlert(const lt::torrent_need_cert_alert * void SessionImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert *alert) { - const TorrentID torrentID {alert->handle.info_hash()}; + const InfoHash infoHash = getInfoHash(alert->handle); + const TorrentID torrentID = infoHash.toTorrentID(); bool found = false; if (const auto iter = m_downloadedMetadata.constFind(torrentID); iter != m_downloadedMetadata.cend()) @@ -6059,7 +6070,6 @@ void SessionImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert m_downloadedMetadata.erase(iter); } #ifdef QBT_USES_LIBTORRENT2 - const InfoHash infoHash {alert->handle.info_hashes()}; if (infoHash.isHybrid()) { const auto altID = TorrentID::fromSHA1Hash(infoHash.v1()); @@ -6081,7 +6091,7 @@ void SessionImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert void SessionImpl::handleFileErrorAlert(const lt::file_error_alert *alert) { - TorrentImpl *const torrent = m_torrents.value(alert->handle.info_hash()); + TorrentImpl *const torrent = getTorrent(alert->handle); if (!torrent) return; @@ -6152,7 +6162,7 @@ void SessionImpl::handlePeerBanAlert(const lt::peer_ban_alert *alert) void SessionImpl::handleUrlSeedAlert(const lt::url_seed_alert *alert) { - const TorrentImpl *torrent = m_torrents.value(alert->handle.info_hash()); + const TorrentImpl *torrent = getTorrent(alert->handle); if (!torrent) return; @@ -6331,14 +6341,8 @@ void SessionImpl::handleStorageMovedAlert(const lt::storage_moved_alert *alert) const Path newPath {QString::fromUtf8(alert->storage_path())}; Q_ASSERT(newPath == currentJob.path); -#ifdef QBT_USES_LIBTORRENT2 - const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes()); -#else - const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hash()); -#endif - - TorrentImpl *torrent = m_torrents.value(id); - const QString torrentName = (torrent ? torrent->name() : id.toString()); + TorrentImpl *torrent = getTorrent(currentJob.torrentHandle); + const QString torrentName = (torrent ? torrent->name() : getInfoHash(currentJob.torrentHandle).toTorrentID().toString()); LogMsg(tr("Moved torrent successfully. Torrent: \"%1\". Destination: \"%2\"").arg(torrentName, newPath.toString())); handleMoveTorrentStorageJobFinished(newPath); @@ -6351,14 +6355,8 @@ void SessionImpl::handleStorageMovedFailedAlert(const lt::storage_moved_failed_a const MoveStorageJob ¤tJob = m_moveStorageQueue.constFirst(); Q_ASSERT(currentJob.torrentHandle == alert->handle); -#ifdef QBT_USES_LIBTORRENT2 - const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes()); -#else - const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hash()); -#endif - - TorrentImpl *torrent = m_torrents.value(id); - const QString torrentName = (torrent ? torrent->name() : id.toString()); + TorrentImpl *torrent = getTorrent(currentJob.torrentHandle); + const QString torrentName = (torrent ? torrent->name() : getInfoHash(currentJob.torrentHandle).toTorrentID().toString()); const Path currentLocation = (torrent ? torrent->actualStorageLocation() : Path(alert->handle.status(lt::torrent_handle::query_save_path).save_path)); const QString errorMessage = QString::fromStdString(alert->message()); @@ -6375,12 +6373,7 @@ void SessionImpl::handleStateUpdateAlert(const lt::state_update_alert *alert) for (const lt::torrent_status &status : alert->status) { -#ifdef QBT_USES_LIBTORRENT2 - const auto id = TorrentID::fromInfoHash(status.info_hashes); -#else - const auto id = TorrentID::fromInfoHash(status.info_hash); -#endif - TorrentImpl *const torrent = m_torrents.value(id); + TorrentImpl *const torrent = getTorrent(status.handle); if (!torrent) continue; @@ -6424,7 +6417,7 @@ void SessionImpl::handleI2PAlert(const lt::i2p_alert *alert) const void SessionImpl::handleTrackerAlert(const lt::tracker_alert *alert) { - TorrentImpl *torrent = m_torrents.value(alert->handle.info_hash()); + TorrentImpl *torrent = getTorrent(alert->handle); if (!torrent) return; @@ -6450,8 +6443,9 @@ void SessionImpl::handleTrackerAlert(const lt::tracker_alert *alert) #ifdef QBT_USES_LIBTORRENT2 void SessionImpl::handleTorrentConflictAlert(const lt::torrent_conflict_alert *alert) { - const auto torrentIDv1 = TorrentID::fromSHA1Hash(alert->metadata->info_hashes().v1); - const auto torrentIDv2 = TorrentID::fromSHA256Hash(alert->metadata->info_hashes().v2); + const InfoHash infoHash = getInfoHash(*alert->metadata); + const auto torrentIDv1 = TorrentID::fromSHA1Hash(infoHash.v1()); + const auto torrentIDv2 = TorrentID::fromSHA256Hash(infoHash.v2()); TorrentImpl *torrent1 = m_torrents.value(torrentIDv1); TorrentImpl *torrent2 = m_torrents.value(torrentIDv2); if (torrent2) diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index e878cf4a6..7b6f6aab7 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -606,6 +606,7 @@ namespace BitTorrent #endif TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms); + TorrentImpl *getTorrent(const lt::torrent_handle &nativeHandle) const; void saveResumeData(); void saveTorrentsQueue();