⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 download.cc

📁 LibTorrent is a BitTorrent library written in C++ for *nix, with a focus on high performance and goo
💻 CC
字号:
// libTorrent - BitTorrent library// Copyright (C) 2005-2006, Jari Sundell//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//// In addition, as a special exception, the copyright holders give// permission to link the code of portions of this program with the// OpenSSL library under certain conditions as described in each// individual source file, and distribute linked combinations// including the two.//// You must obey the GNU General Public License in all respects for// all of the code used other than OpenSSL.  If you modify file(s)// with this exception, you may extend this exception to your version// of the file(s), but you are not obligated to do so.  If you do not// wish to do so, delete this exception statement from your version.// If you delete this exception statement from all source files in the// program, then also delete it here.//// Contact:  Jari Sundell <jaris@ifi.uio.no>////           Skomakerveien 33//           3185 Skoppum, NORWAY#include "config.h"#include <rak/functional.h>#include <sigc++/bind.h>#include <sigc++/hide.h>#include "data/chunk_list.h"#include "data/hash_queue.h"#include "data/hash_torrent.h"#include "download/available_list.h"#include "download/choke_manager.h"#include "download/chunk_selector.h"#include "download/chunk_statistics.h"#include "download/download_wrapper.h"#include "protocol/peer_connection_base.h"#include "protocol/peer_factory.h"#include "download/download_info.h"#include "tracker/tracker_manager.h"#include "exceptions.h"#include "block.h"#include "block_list.h"#include "download.h"#include "file_list.h"#include "object.h"#include "peer_info.h"#include "tracker_list.h"namespace torrent {voidDownload::open() {  m_ptr->open();}voidDownload::close() {  if (m_ptr->info()->is_active())    stop();  m_ptr->close();}voidDownload::start() {  if (!m_ptr->hash_checker()->is_checked())    throw client_error("Tried to start an unchecked download");  if (!m_ptr->info()->is_open())    throw client_error("Tried to start a closed download");  if (m_ptr->info()->is_active())    return;  m_ptr->main()->start();  m_ptr->main()->tracker_manager()->set_active(true);  // Either the client queued a completed request, or it is still  // sending the stopped request. Don't send started nor reset the  // baseline.  //  // Check for stopped request.  if (m_ptr->main()->tracker_manager()->is_busy())    return;  // Reset the uploaded/download baseline when we restart the download  // so that broken trackers get the right uploaded ratio.  m_ptr->info()->set_uploaded_baseline(m_ptr->info()->up_rate()->total());  m_ptr->info()->set_completed_baseline(m_ptr->info()->slot_completed()());  m_ptr->main()->tracker_manager()->send_start();}voidDownload::stop() {  if (!m_ptr->info()->is_active())    return;  m_ptr->main()->stop();  m_ptr->main()->tracker_manager()->set_active(false);  m_ptr->main()->tracker_manager()->send_stop();}boolDownload::hash_check(bool tryQuick) {  if (m_ptr->hash_checker()->is_checking())    return m_ptr->hash_checker()->start(tryQuick);  if (!m_ptr->info()->is_open() || m_ptr->info()->is_active())    throw client_error("Download::hash_check(...) called on a closed or active download.");  if (m_ptr->hash_checker()->is_checked())    throw client_error("Download::hash_check(...) called but already hash checked.");  // The bitfield still hasn't been allocated, so no resume data was  // given.   if (m_ptr->main()->content()->bitfield()->empty()) {    m_ptr->main()->content()->bitfield()->allocate();    m_ptr->main()->content()->bitfield()->unset_all();    m_ptr->hash_checker()->ranges().insert(0, m_ptr->main()->content()->chunk_total());    // Make sure other book-keeping is cleared, like file progress.  } else {    m_ptr->main()->content()->update_done();  }  return m_ptr->hash_checker()->start(tryQuick);}// Propably not correct, need to clear content, etc.voidDownload::hash_stop() {  if (!m_ptr->hash_checker()->is_checking())    return;  // Stop the hashing first as we need to make sure all chunks are  // released when DownloadMain::close() is called.  m_ptr->hash_checker()->clear();  // Clear after m_hash to ensure that the empty hash done signal does  // not get passed to HashTorrent.  m_ptr->hash_checker()->get_queue()->remove(m_ptr);}boolDownload::is_open() const {  return m_ptr->info()->is_open();}boolDownload::is_active() const {  return m_ptr->info()->is_active();}boolDownload::is_hash_checked() const {  return m_ptr->hash_checker()->is_checked();}boolDownload::is_hash_checking() const {  return m_ptr->hash_checker()->is_checking();}const std::string&Download::name() const {  if (m_ptr == NULL)    throw internal_error("Download::name() m_ptr == NULL.");  return m_ptr->info()->name();}const std::string&Download::info_hash() const {  if (m_ptr == NULL)    throw internal_error("Download::info_hash() m_ptr == NULL.");  return m_ptr->info()->hash();}const std::string&Download::local_id() const {  if (m_ptr == NULL)    throw internal_error("Download::local_id() m_ptr == NULL.");  return m_ptr->info()->local_id();}uint32_tDownload::creation_date() const {  if (m_ptr->bencode()->has_key_value("creation date"))    return m_ptr->bencode()->get_key_value("creation date");  else    return 0;}Object*Download::bencode() {  return m_ptr->bencode();}const Object*Download::bencode() const {  return m_ptr->bencode();}FileListDownload::file_list() const {  return FileList(m_ptr->main()->content()->entry_list());}TrackerListDownload::tracker_list() const {  return TrackerList(m_ptr->main()->tracker_manager());}PeerList*Download::peer_list() {  return m_ptr->main()->peer_list();}const PeerList*Download::peer_list() const {  return m_ptr->main()->peer_list();}const TransferList*Download::transfer_list() const {  return m_ptr->main()->delegator()->transfer_list();}Rate*Download::down_rate() {  return m_ptr->info()->down_rate();}const Rate*Download::down_rate() const {  return m_ptr->info()->down_rate();}Rate*Download::up_rate() {  return m_ptr->info()->up_rate();}const Rate*Download::up_rate() const {  return m_ptr->info()->up_rate();}uint64_tDownload::bytes_done() const {  uint64_t a = 0;   Delegator* d = m_ptr->main()->delegator();  for (TransferList::const_iterator itr1 = d->transfer_list()->begin(), last1 = d->transfer_list()->end(); itr1 != last1; ++itr1)    for (BlockList::const_iterator itr2 = (*itr1)->begin(), last2 = (*itr1)->end(); itr2 != last2; ++itr2)      if (itr2->is_finished())        a += itr2->piece().length();    return a + m_ptr->main()->content()->bytes_completed();}uint64_tDownload::bytes_total() const {  return m_ptr->main()->content()->entry_list()->bytes_size();}uint64_tDownload::free_diskspace() const {  return m_ptr->main()->content()->entry_list()->free_diskspace();}uint32_tDownload::chunks_size() const {  return m_ptr->main()->content()->chunk_size();}uint32_tDownload::chunks_done() const {  return m_ptr->main()->content()->chunks_completed();}uint32_t Download::chunks_total() const {  return m_ptr->main()->content()->chunk_total();}uint32_t Download::chunks_hashed() const {  return m_ptr->hash_checker()->position();}const uint8_t*Download::chunks_seen() const {  return !m_ptr->main()->chunk_statistics()->empty() ? &*m_ptr->main()->chunk_statistics()->begin() : NULL;}voidDownload::set_chunks_done(uint32_t chunks) {  if (m_ptr->info()->is_open())    throw input_error("Download::set_chunks_done(...) Download is open.");  m_ptr->main()->content()->bitfield()->set_size_set(chunks);}voidDownload::set_bitfield(bool allSet) {  if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())    throw input_error("Download::set_bitfield(...) Download in invalid state.");  Bitfield* bitfield = m_ptr->main()->content()->bitfield();  bitfield->allocate();  if (allSet)    bitfield->set_all();  else    bitfield->unset_all();    m_ptr->hash_checker()->ranges().clear();}voidDownload::set_bitfield(uint8_t* first, uint8_t* last) {  if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())    throw input_error("Download::set_bitfield(...) Download in invalid state.");  if (std::distance(first, last) != (ptrdiff_t)m_ptr->main()->content()->bitfield()->size_bytes())    throw input_error("Download::set_bitfield(...) Invalid length.");  Bitfield* bitfield = m_ptr->main()->content()->bitfield();  bitfield->allocate();  std::memcpy(bitfield->begin(), first, bitfield->size_bytes());  bitfield->update();    m_ptr->hash_checker()->ranges().clear();}voidDownload::clear_range(uint32_t first, uint32_t last) {  if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking() || m_ptr->main()->content()->bitfield()->empty())    throw input_error("Download::clear_range(...) Download in invalid state.");  m_ptr->hash_checker()->ranges().insert(first, last);  m_ptr->main()->content()->bitfield()->unset_range(first, last);} const Bitfield*Download::bitfield() const {  return m_ptr->main()->content()->bitfield();}voidDownload::sync_chunks() {  m_ptr->main()->chunk_list()->sync_chunks(ChunkList::sync_all | ChunkList::sync_force);}uint32_tDownload::peers_min() const {  return m_ptr->main()->connection_list()->get_min_size();}uint32_tDownload::peers_max() const {  return m_ptr->main()->connection_list()->get_max_size();}uint32_tDownload::peers_connected() const {  return m_ptr->main()->connection_list()->size();}uint32_tDownload::peers_not_connected() const {  return m_ptr->main()->peer_list()->available_list()->size();}uint32_tDownload::peers_complete() const {  return m_ptr->main()->chunk_statistics()->complete();}uint32_tDownload::peers_accounted() const {  return m_ptr->main()->chunk_statistics()->accounted();}uint32_tDownload::peers_currently_unchoked() const {  return m_ptr->main()->choke_manager()->currently_unchoked();}uint32_tDownload::peers_currently_interested() const {  return m_ptr->main()->choke_manager()->currently_interested();}boolDownload::accepting_new_peers() const {  return m_ptr->info()->is_accepting_new_peers();}uint32_tDownload::uploads_max() const {  return m_ptr->main()->choke_manager()->max_unchoked();}  voidDownload::set_peers_min(uint32_t v) {  if (v > (1 << 16))    throw input_error("Min peer connections must be between 0 and 2^16.");    m_ptr->main()->connection_list()->set_min_size(v);  m_ptr->main()->receive_connect_peers();}voidDownload::set_peers_max(uint32_t v) {  if (v > (1 << 16))    throw input_error("Max peer connections must be between 0 and 2^16.");  m_ptr->main()->connection_list()->set_max_size(v);}voidDownload::set_uploads_max(uint32_t v) {  if (v > (1 << 16))    throw input_error("Max uploads must be between 0 and 2^16.");  m_ptr->main()->choke_manager()->set_max_unchoked(v);  m_ptr->main()->choke_manager()->balance();}Download::ConnectionTypeDownload::connection_type() const {  return (ConnectionType)m_ptr->connection_type();}voidDownload::set_connection_type(ConnectionType t) {  switch (t) {  case CONNECTION_LEECH:    m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionDefault);    break;  case CONNECTION_SEED:    m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionSeed);    break;  default:    throw input_error("torrent::Download::set_connection_type(...) received an unknown type.");  };  m_ptr->set_connection_type(t);}voidDownload::update_priorities() {  m_ptr->receive_update_priorities();}voidDownload::peer_list(PList& pList) {  std::for_each(m_ptr->main()->connection_list()->begin(), m_ptr->main()->connection_list()->end(),                rak::bind1st(std::mem_fun<void,PList,PList::const_reference>(&PList::push_back), &pList));}PeerDownload::peer_find(const std::string& id) {  ConnectionList::iterator itr =    std::find_if(m_ptr->main()->connection_list()->begin(), m_ptr->main()->connection_list()->end(),                 rak::equal(id, rak::on(std::mem_fun(&PeerConnectionBase::c_peer_info), std::mem_fun(&PeerInfo::id))));  return itr != m_ptr->main()->connection_list()->end() ? *itr : NULL;}voidDownload::disconnect_peer(Peer p) {  m_ptr->main()->connection_list()->erase(p.ptr(), 0);}sigc::connectionDownload::signal_download_done(Download::slot_void_type s) {  return m_ptr->signal_download_done().connect(s);}sigc::connectionDownload::signal_hash_done(Download::slot_void_type s) {  return m_ptr->signal_initial_hash().connect(s);}sigc::connectionDownload::signal_peer_connected(Download::slot_peer_type s) {  return m_ptr->signal_peer_connected().connect(s);}sigc::connectionDownload::signal_peer_disconnected(Download::slot_peer_type s) {  return m_ptr->signal_peer_disconnected().connect(s);}sigc::connectionDownload::signal_tracker_succeded(Download::slot_void_type s) {  return m_ptr->signal_tracker_success().connect(s);}sigc::connectionDownload::signal_tracker_failed(Download::slot_string_type s) {  return m_ptr->signal_tracker_failed().connect(s);}sigc::connectionDownload::signal_tracker_dump(Download::slot_dump_type s) {  return m_ptr->info()->signal_tracker_dump().connect(s);}sigc::connectionDownload::signal_chunk_passed(Download::slot_chunk_type s) {  return m_ptr->signal_chunk_passed().connect(s);}sigc::connectionDownload::signal_chunk_failed(Download::slot_chunk_type s) {  return m_ptr->signal_chunk_failed().connect(s);}sigc::connectionDownload::signal_network_log(slot_string_type s) {  return m_ptr->info()->signal_network_log().connect(s);}sigc::connectionDownload::signal_storage_error(slot_string_type s) {  return m_ptr->info()->signal_storage_error().connect(s);}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -