📄 download_list.cc
字号:
// rTorrent - BitTorrent client// 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 <algorithm>#include <iostream>#include <sigc++/bind.h>#include <torrent/exceptions.h>#include <torrent/object.h>#include <torrent/object_stream.h>#include <torrent/resume.h>#include <torrent/torrent.h>#include "rak/functional.h"#include "globals.h"#include "manager.h"#include "download.h"#include "download_list.h"#include "download_store.h"namespace core {inline voidDownloadList::check_contains(Download* d) {#ifdef USE_EXTRA_DEBUG if (std::find(begin(), end(), d) == end()) throw torrent::client_error("DownloadList::check_contains(...) failed.");#endif}struct download_list_call { download_list_call(Download* d) : m_download(d) {} void operator () (const DownloadList::slot_map::value_type& s) { s.second(m_download); } Download* m_download;}; voidDownloadList::clear() { std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadList::close), this)); std::for_each(begin(), end(), rak::call_delete<Download>()); base_type::clear();}voidDownloadList::session_save() { std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadStore::save), control->core()->download_store()));}Download*DownloadList::create(std::istream* str, bool printLog) { torrent::Object* object = new torrent::Object; torrent::Download download; try { *str >> *object; // Catch, delete. if (str->fail()) throw torrent::input_error("Could not create download, the input is not a valid torrent."); download = torrent::download_add(object); } catch (torrent::local_error& e) { delete object; if (printLog) control->core()->push_log(e.what()); return NULL; } // There's no non-critical exceptions that should be throwable by // the ctor, so don't catch. return new Download(download);}DownloadList::iteratorDownloadList::insert(Download* download) { iterator itr = base_type::insert(end(), download); try { (*itr)->download()->signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::received_finished), download)); (*itr)->download()->signal_hash_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::hash_done), download)); std::for_each(slot_map_insert().begin(), slot_map_insert().end(), download_list_call(*itr)); } catch (torrent::local_error& e) { // Should perhaps relax this, just print an error and remove the // downloads? throw torrent::client_error("Caught during DownloadList::insert(...): " + std::string(e.what())); } return itr;}voidDownloadList::erase(Download* download) { check_contains(download); erase(std::find(begin(), end(), download));}DownloadList::iteratorDownloadList::erase(iterator itr) { if (itr == end()) throw torrent::client_error("DownloadList::erase(...) could not find download."); // Makes sure close doesn't restart hashing of this download. (*itr)->set_hash_failed(true); close(*itr); control->core()->download_store()->remove(*itr); std::for_each(slot_map_erase().begin(), slot_map_erase().end(), download_list_call(*itr)); torrent::download_remove(*(*itr)->download()); delete *itr; return base_type::erase(itr);}boolDownloadList::open(Download* download) { try { open_throw(download); return true; } catch (torrent::local_error& e) { control->core()->push_log(e.what()); return false; }}voidDownloadList::open_throw(Download* download) { check_contains(download); if (download->download()->is_open()) return; download->download()->open(); std::for_each(slot_map_open().begin(), slot_map_open().end(), download_list_call(download));}voidDownloadList::close(Download* download) { try { close_throw(download); } catch (torrent::local_error& e) { control->core()->push_log(e.what()); }}voidDownloadList::close_throw(Download* download) { check_contains(download); // When pause gets called it will clear the initial hash check state // and set hash failed. This should ensure hashing doesn't restart // until resume gets called. pause(download); // Check for is_open after pause due to hashing. if (!download->is_open()) return; // Save the torrent on close, this covers shutdown and if a torrent // is manually closed which would clear the progress data. For // better crash protection, save regulary in addition to this. // // Used to be in pause, but this was wrong for rehashing etc. // // Reconsider this save. Should be done explicitly when shutting down. //control->core()->download_store()->save(download); download->download()->close(); if (!download->is_hash_failed() && download->variable()->get_value("hashing") != Download::variable_hashing_stopped) throw torrent::client_error("DownloadList::close_throw(...) called but we're going into a hashing loop."); std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download)); std::for_each(slot_map_close().begin(), slot_map_close().end(), download_list_call(download));}voidDownloadList::start_normal(Download* download) { check_contains(download); // Clear hash failed as we're doing a manual start and want to try // hashing again. download->set_hash_failed(false); download->variable()->set("state", (int64_t)1); resume(download);}boolDownloadList::start_try(Download* download) { check_contains(download); // Also don't start if the state is one of those that indicate we // were manually stopped? if (download->is_hash_failed() || download->variable()->get_value("ignore_commands") != 0) return false; // Don't clear the hash failed as this function is used by scripts, // etc. download->variable()->set("state", (int64_t)1); resume(download); return true;}voidDownloadList::stop_normal(Download* download) { check_contains(download);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -