Browse Source

* Removed core::HashQueue, using the "hashing" view and a function in

core::Manager instead.

* Added a new :rtorrent:hashing state so we can distinguish between
initial hashing and manual rehashes. The former is cleared if the
download is paused.

* Added a hash failed flag to core::Download. This is used to skip
entries in the hashing view that either failed to open or are in the
process of being erased from DownloadList.

* torrent::Bitfield::unset was incrementing, rather than decrementing,
the m_set counter.

* Replaced all torrent::internal_error's in rtorrent with
torrent::client_error.

* ^D now checks :rtorrent:state to decide whetever to stop or erase a
download. Downloads queued for hashing will now stop rather than be
deleted.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@688 e378c898-3ddf-0310-93e7-cc216c733640
pull/30/head
rakshasa 20 years ago
parent
commit
d4706da4d5
  1. 6
      src/command_scheduler.cc
  2. 4
      src/command_scheduler_item.cc
  3. 1
      src/control.cc
  4. 2
      src/core/Makefile.am
  5. 2
      src/core/download.cc
  6. 16
      src/core/download.h
  7. 122
      src/core/download_list.cc
  8. 6
      src/core/download_list.h
  9. 125
      src/core/hash_queue.cc
  10. 109
      src/core/hash_queue.h
  11. 43
      src/core/manager.cc
  12. 11
      src/core/manager.h
  13. 4
      src/core/scheduler.cc
  14. 16
      src/core/view.cc
  15. 3
      src/core/view.h
  16. 3
      src/core/view_manager.cc
  17. 14
      src/display/utils.cc
  18. 2
      src/display/window_download_list.cc
  19. 6
      src/ui/download_list.cc
  20. 12
      src/ui/element_file_list.cc
  21. 14
      src/ui/element_tracker_list.cc
  22. 2
      src/utils/variable_map.cc

6
src/command_scheduler.cc

@ -85,10 +85,10 @@ CommandScheduler::erase(iterator itr) {
void
CommandScheduler::call_item(value_type item) {
if (item->is_queued())
throw torrent::internal_error("CommandScheduler::call_item(...) called but item is still queued.");
throw torrent::client_error("CommandScheduler::call_item(...) called but item is still queued.");
if (std::find(begin(), end(), item) == end())
throw torrent::internal_error("CommandScheduler::call_item(...) called but the item isn't in the scheduler.");
throw torrent::client_error("CommandScheduler::call_item(...) called but the item isn't in the scheduler.");
// Remove the item before calling the command if it should be
// removed.
@ -110,7 +110,7 @@ CommandScheduler::call_item(value_type item) {
}
if (next <= cachedTime)
throw torrent::internal_error("CommandScheduler::call_item(...) tried to schedule a zero interval item.");
throw torrent::client_error("CommandScheduler::call_item(...) tried to schedule a zero interval item.");
item->enable(next);
}

4
src/command_scheduler_item.cc

@ -47,7 +47,7 @@ CommandSchedulerItem::~CommandSchedulerItem() {
void
CommandSchedulerItem::enable(rak::timer t) {
if (t == rak::timer())
throw torrent::internal_error("CommandSchedulerItem::enable() t == rak::timer().");
throw torrent::client_error("CommandSchedulerItem::enable() t == rak::timer().");
if (is_queued())
disable();
@ -71,7 +71,7 @@ CommandSchedulerItem::next_time_scheduled() const {
return rak::timer();
if (m_timeScheduled == rak::timer())
throw torrent::internal_error("CommandSchedulerItem::next_time_scheduled() m_timeScheduled == rak::timer().");
throw torrent::client_error("CommandSchedulerItem::next_time_scheduled() m_timeScheduled == rak::timer().");
rak::timer next = m_timeScheduled;

1
src/control.cc

@ -113,6 +113,7 @@ Control::initialize() {
m_core->listen_open();
m_core->download_store()->enable(m_variables->get_value("session_lock"));
m_core->set_hashing_view(*m_viewManager->find_throw("hashing"));
m_scheduler->set_view(*m_viewManager->find_throw("scheduler"));
m_ui->init(this);

2
src/core/Makefile.am

@ -14,8 +14,6 @@ libsub_core_a_SOURCES = \
download_slot_map.h \
download_store.cc \
download_store.h \
hash_queue.cc \
hash_queue.h \
http_queue.cc \
http_queue.h \
log.cc \

2
src/core/download.cc

@ -57,6 +57,8 @@ Download::Download(download_type d) :
m_fileList(d.file_list()),
m_trackerList(d.tracker_list()),
m_hashFailed(false),
m_chunksFailed(0) {
m_connTrackerSucceded = m_download.signal_tracker_succeded(sigc::bind(sigc::mem_fun(*this, &Download::receive_tracker_msg), ""));

16
src/core/download.h

@ -56,15 +56,25 @@ public:
typedef utils::VariableMap variable_map_type;
static const int64_t variable_hashing_stopped = 0;
static const int64_t variable_hashing_started = 1;
static const int64_t variable_hashing_initial = 1;
static const int64_t variable_hashing_last = 2;
static const int64_t variable_hashing_rehash = 3;
Download(download_type d);
~Download();
bool is_open() const { return m_download.is_open(); }
bool is_active() const { return m_download.is_active(); }
inline bool is_done() const { return m_download.chunks_done() == m_download.chunks_total(); }
bool is_done() const { return m_download.chunks_done() == m_download.chunks_total(); }
// FIXME: Fixed a bug in libtorrent that caused is_hash_checked to
// return true when the torrent is closed. Remove this redundant
// test in the next milestone.
bool is_hash_checked() const { return m_download.is_open() && m_download.is_hash_checked(); }
bool is_hash_checking() const { return m_download.is_hash_checking(); }
bool is_hash_failed() const { return m_hashFailed; }
void set_hash_failed(bool v) { m_hashFailed = v; }
variable_map_type* variable() { return &m_variables; }
std::string variable_string(const std::string& key) { return m_variables.get_string(key); }
@ -127,6 +137,8 @@ private:
file_list_type m_fileList;
tracker_list_type m_trackerList;
bool m_hashFailed;
std::string m_message;
uint32_t m_chunksFailed;

122
src/core/download_list.cc

@ -47,7 +47,6 @@
#include "rak/functional.h"
#include "globals.h"
#include "hash_queue.h"
#include "manager.h"
#include "download.h"
@ -60,7 +59,7 @@ inline void
DownloadList::check_contains(Download* d) {
#ifdef USE_EXTRA_DEBUG
if (std::find(begin(), end(), d) == end())
throw torrent::internal_error("DownloadList::check_contains(...) failed.");
throw torrent::client_error("DownloadList::check_contains(...) failed.");
#endif
}
@ -121,12 +120,14 @@ DownloadList::insert(Download* 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::internal_error("Caught during DownloadList::insert(...): " + std::string(e.what()));
throw torrent::client_error("Caught during DownloadList::insert(...): " + std::string(e.what()));
}
return itr;
@ -142,7 +143,10 @@ DownloadList::erase(Download* download) {
DownloadList::iterator
DownloadList::erase(iterator itr) {
if (itr == end())
throw torrent::internal_error("DownloadList::erase(...) could not find download.");
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);
@ -199,10 +203,12 @@ void
DownloadList::close_throw(Download* download) {
check_contains(download);
if (!download->download()->is_open())
if (!download->is_open())
return;
if (download->download()->is_active())
// When pause gets called it will clear the initial hash checking.
if (download->is_active())
pause(download);
// Save the torrent on close, this covers shutdown and if a torrent
@ -214,18 +220,32 @@ DownloadList::close_throw(Download* download) {
// Reconsider this save. Should be done explicitly when shutting down.
//control->core()->download_store()->save(download);
if (control->core()->hash_queue()->is_queued(download)) {
control->core()->hash_queue()->remove(download);
download->download()->close();
// FIXME: Urgh, need to do something sane when closing a download
// that has been queued for hashing. ATM just close the torrent and
// call the hash_removed slots. This might open and restart the
// hashing of this torrent.
// Hash removed slot must be called after close as we can't atm
// stop already started hash checks except through close.
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
// if (download->is_hash_checking()) {
// download->download()->close();
} else {
download->download()->close();
}
// // Hash removed slot must be called after close as we can't atm
// // stop already started hash checks except through close.
// std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
// } else {
// download->download()->close();
// }
// But this isn't correct either, i think... ATM do the borking
// thing, the hash queue won't be updated. Need to properly handle
// erasing a download.
// Propably should do its own thingie in erase rather than calling
// close.
download->download()->close();
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));
}
@ -256,34 +276,27 @@ DownloadList::resume(Download* download) {
if (download->download()->is_active())
return;
// Properly escape when resume get's called during hashing. The
// 'state' is changed by the call to DownloadList::start so it
// will automagically start afterwards.
if (control->core()->hash_queue()->is_queued(download))
return;
download->variable()->set("state_changed", cachedTime.seconds());
open_throw(download);
// Manual or end-of-download rehashing clears the resume data so
// we can just start the hashing again without clearing it again.
//
// It is also assumed the is_hash_checked flag gets cleared when
// 'hashing' was set.
if (!download->download()->is_hash_checked()) {
if (!download->is_hash_checked()) {
download->set_hash_failed(false);
// Set 'hashing' to started if hashing wasn't started, else keep
// the old value.
if (download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
download->variable()->set("hashing", Download::variable_hashing_started);
download->variable()->set("hashing", Download::variable_hashing_initial);
control->core()->hash_queue()->insert(download);
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
return;
}
download->variable()->set("state_changed", cachedTime.seconds());
open_throw(download);
if (download->is_done()) {
download->set_connection_type(download->variable()->get_string("connection_seed"));
} else {
@ -314,11 +327,10 @@ DownloadList::pause(Download* download) {
try {
if (control->core()->hash_queue()->is_queued(download)) {
control->core()->hash_queue()->remove(download);
// Don't stop if we're doing the final hashing.
if (download->variable()->get_value("hashing") == Download::variable_hashing_initial) {
download->variable()->set("hashing", Download::variable_hashing_stopped);
// Hash removed slot must be called after close as we can't atm
// stop already started hash checks except through close.
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
}
@ -347,37 +359,20 @@ DownloadList::check_hash(Download* download) {
try {
download->variable()->set("hashing", Download::variable_hashing_started);
check_hash_throw(download);
download->variable()->set("hashing", Download::variable_hashing_rehash);
hash_clear(download);
} catch (torrent::local_error& e) {
control->core()->push_log(e.what());
}
}
// Throw in addition to not setting 'hashing'.
void
DownloadList::check_hash_throw(Download* download) {
check_contains(download);
close_throw(download);
download->download()->hash_resume_clear();
open_throw(download);
// If any more stuff is added here, make sure resume etc are still
// correct.
control->core()->hash_queue()->insert(download);
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
}
void
DownloadList::hash_done(Download* download) {
check_contains(download);
if (!download->download()->is_hash_checked() ||
download->download()->is_hash_checking() ||
download->download()->is_active())
throw torrent::internal_error("DownloadList::hash_done(...) download in invalid state.");
if (!download->is_hash_checked() || download->is_hash_checking() || download->is_active())
throw torrent::client_error("DownloadList::hash_done(...) download in invalid state.");
// Need to find some sane conditional here. Can we check the total
// downloaded to ensure something was transferred, thus we didn't
@ -392,7 +387,8 @@ DownloadList::hash_done(Download* download) {
download->variable()->set("hashing", Download::variable_hashing_stopped);
switch (hashing) {
case Download::variable_hashing_started:
case Download::variable_hashing_initial:
case Download::variable_hashing_rehash:
// Normal re/hashing.
if (download->is_done())
@ -432,6 +428,20 @@ DownloadList::hash_done(Download* download) {
std::for_each(slot_map_hash_done().begin(), slot_map_hash_done().end(), download_list_call(download));
}
void
DownloadList::hash_clear(Download* download) {
check_contains(download);
close_throw(download);
download->download()->hash_resume_clear();
download->set_hash_failed(false);
// If any more stuff is added here, make sure resume etc are still
// correct.
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
}
void
DownloadList::received_finished(Download* download) {
check_contains(download);
@ -441,7 +451,7 @@ DownloadList::received_finished(Download* download) {
// trigger correctly, also so it can bork on missing data.
download->variable()->set("hashing", Download::variable_hashing_last);
check_hash_throw(download);
hash_clear(download);
} else {
confirm_finished(download);

6
src/core/download_list.h

@ -100,9 +100,6 @@ public:
void pause(Download* d);
void check_hash(Download* d);
void check_hash_throw(Download* d);
void hash_done(Download* d);
enum {
SLOTS_INSERT,
@ -171,6 +168,9 @@ public:
static void erase_key(slot_map& sm, const std::string& key) { sm.erase(key); }
private:
void hash_done(Download* d);
void hash_clear(Download* d);
inline void check_contains(Download* d);
void received_finished(Download* d);

125
src/core/hash_queue.cc

@ -1,125 +0,0 @@
// 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 <stdexcept>
#include <sigc++/bind.h>
#include "download.h"
#include "download_list.h"
#include "rak/functional.h"
#include "hash_queue.h"
namespace core {
bool
HashQueue::is_queued(Download* download) const {
return
download->download()->is_hash_checking() ||
std::find_if(begin(), end(), rak::equal(download, std::mem_fun(&HashQueueNode::download))) != end();
}
void
HashQueue::insert(Download* download) {
if (download->download()->is_hash_checking() || find(download) != end())
return;
if (download->download()->is_hash_checked()) {
m_downloadList->hash_done(download);
return;
}
if (find(download) != end())
throw torrent::internal_error("HashQueue::insert(...) download already in queue.");
iterator itr = Base::insert(end(), new HashQueueNode(download));
(*itr)->set_connection(download->download()->signal_hash_done(sigc::bind(sigc::mem_fun(*this, &HashQueue::receive_hash_done), download)));
fill_queue();
}
void
HashQueue::remove(Download* d) {
iterator itr = find(d);
if (itr == end())
return;
// We don't do anything if we're already checking, just disconnect.
// if ((*itr)->download()->download()->is_hash_checking()) {
// // What do we do if we're already checking?
// }
delete *itr;
Base::erase(itr);
fill_queue();
}
HashQueue::iterator
HashQueue::find(Download* d) {
return std::find_if(begin(), end(), rak::equal(d, std::mem_fun(&HashQueueNode::download)));
}
void
HashQueue::receive_hash_done(Download* d) {
iterator itr = find(d);
if (itr == end())
return;
delete *itr;
Base::erase(itr);
m_downloadList->hash_done(d);
fill_queue();
}
void
HashQueue::fill_queue() {
if (empty() || front()->download()->download()->is_hash_checking())
return;
if (front()->download()->download()->is_hash_checked())
throw std::logic_error("core::HashQueue::fill_queue() encountered a checked hash");
front()->download()->download()->hash_check();
}
}

109
src/core/hash_queue.h

@ -1,109 +0,0 @@
// 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
#ifndef RTORRENT_CORE_HASH_QUEUE_H
#define RTORRENT_CORE_HASH_QUEUE_H
#include <list>
#include <sigc++/slot.h>
#include <sigc++/connection.h>
namespace core {
class Download;
class DownloadList;
class HashQueueNode;
class HashQueue : private std::list<HashQueueNode*> {
public:
typedef std::list<HashQueueNode*> Base;
using Base::iterator;
using Base::const_iterator;
using Base::reverse_iterator;
using Base::const_reverse_iterator;
using Base::begin;
using Base::end;
using Base::rbegin;
using Base::rend;
using Base::front;
using Base::back;
using Base::empty;
using Base::size;
// Replace 'dl' with a slot.
HashQueue(DownloadList* dl) : m_downloadList(dl) {}
bool is_queued(Download* download) const;
void insert(Download* d);
// It's safe to try to remove downloads not in the queue. The hash
// checking is not stopped if it has already started.
void remove(Download* d);
iterator find(Download* d);
private:
void receive_hash_done(Download* d);
void fill_queue();
DownloadList* m_downloadList;
};
class HashQueueNode {
public:
HashQueueNode(Download* d) : m_download(d) {}
~HashQueueNode() { disconnect(); }
void disconnect() { m_connection.disconnect(); }
Download* download() { return m_download; }
void set_connection(sigc::connection c) { m_connection = c; }
private:
Download* m_download;
sigc::connection m_connection;
};
}
#endif

43
src/core/manager.cc

@ -60,11 +60,11 @@
#include "download.h"
#include "download_factory.h"
#include "download_store.h"
#include "hash_queue.h"
#include "http_queue.h"
#include "manager.h"
#include "poll_manager_epoll.h"
#include "poll_manager_select.h"
#include "view.h"
namespace core {
@ -114,6 +114,8 @@ delete_tied(Download* d) {
}
Manager::Manager() :
m_hashingView(NULL),
m_pollManager(NULL),
m_portFirst(6890),
m_portLast(6999) {
@ -122,17 +124,24 @@ Manager::Manager() :
m_downloadList = new DownloadList();
m_httpQueue = new HttpQueue();
m_hashQueue = new HashQueue(m_downloadList);
}
Manager::~Manager() {
delete m_downloadList;
delete m_hashQueue;
delete m_downloadStore;
delete m_httpQueue;
}
void
Manager::set_hashing_view(View* v) {
if (v == NULL || m_hashingView != NULL)
throw torrent::client_error("Manager::set_hashing_view(...) received NULL or is already set.");
m_hashingView = v;
v->signal_changed().connect(sigc::mem_fun(this, &Manager::receive_hashing_changed));
}
void
Manager::initialize_first() {
if ((m_pollManager = PollManagerEPoll::create(sysconf(_SC_OPEN_MAX))) != NULL)
@ -360,4 +369,32 @@ Manager::try_create_download_expand(const std::string& uri, bool start, bool pri
try_create_download(uri, start, printLog, tied);
}
// DownloadList's hashing related functions don't actually start the
// hashing, it only reacts to events. This functions checks the
// hashing view and starts hashing if nessesary.
void
Manager::receive_hashing_changed() {
if (m_hashingView->empty_visible() ||
std::find_if(m_hashingView->begin_visible(), m_hashingView->end_visible(), std::mem_fun(&Download::is_hash_checking)) != m_hashingView->end_visible())
return;
for (View::iterator itr = m_hashingView->begin_visible(), last = m_hashingView->end_visible(); itr != last; ++itr) {
try {
if ((*itr)->is_hash_checked())
throw torrent::client_error("core::Manager::receive_hashing_changed() hash already checked.");
m_downloadList->open_throw(*itr);
(*itr)->download()->hash_check();
return;
} catch (torrent::local_error& e) {
(*itr)->set_hash_failed(true);
push_log(e.what());
}
}
}
}

11
src/core/manager.h

@ -50,8 +50,8 @@ namespace torrent {
namespace core {
class DownloadStore;
class HashQueue;
class HttpQueue;
class View;
class Manager {
public:
@ -65,9 +65,11 @@ public:
DownloadList* download_list() { return m_downloadList; }
DownloadStore* download_store() { return m_downloadStore; }
HashQueue* hash_queue() { return m_hashQueue; }
HttpQueue* http_queue() { return m_httpQueue; }
View* hashing_view() { return m_hashingView; }
void set_hashing_view(View* v);
PollManager* get_poll_manager() { return m_pollManager; }
Log& get_log_important() { return m_logImportant; }
Log& get_log_complete() { return m_logComplete; }
@ -103,11 +105,14 @@ private:
void receive_http_failed(std::string msg);
void receive_hashing_changed();
DownloadList* m_downloadList;
DownloadStore* m_downloadStore;
HashQueue* m_hashQueue;
HttpQueue* m_httpQueue;
View* m_hashingView;
PollManager* m_pollManager;
Log m_logImportant;
Log m_logComplete;

4
src/core/scheduler.cc

@ -82,7 +82,7 @@ Scheduler::update() {
for (View::iterator itr = m_view->begin_visible(), last = m_view->end_visible(); curActive > target; ++itr) {
if (itr == last)
throw torrent::internal_error("Scheduler::update() loop bork.");
throw torrent::client_error("Scheduler::update() loop bork.");
if ((*itr)->is_active()) {
m_downloadList->pause(*itr);
@ -94,7 +94,7 @@ Scheduler::update() {
for (View::iterator itr = m_view->begin_visible(), last = m_view->end_visible(); curActive < m_maxActive; ++itr) {
if (itr == last)
throw torrent::internal_error("Scheduler::update() loop bork.");
throw torrent::client_error("Scheduler::update() loop bork.");
if (!(*itr)->is_active()) {
m_downloadList->resume(*itr);

16
src/core/view.cc

@ -60,15 +60,15 @@ View::~View() {
void
View::initialize(const std::string& name, core::DownloadList* dlist) {
if (!m_name.empty())
throw torrent::internal_error("View::initialize(...) called on an already initialized view.");
throw torrent::client_error("View::initialize(...) called on an already initialized view.");
if (name.empty())
throw torrent::internal_error("View::initialize(...) called with an empty name.");
throw torrent::client_error("View::initialize(...) called with an empty name.");
std::string key = "0_view_" + name;
if (dlist->has_slot_insert(key) || dlist->has_slot_erase(key))
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
throw torrent::client_error("View::initialize(...) duplicate key name found in DownloadList.");
m_name = name;
m_list = dlist;
@ -167,7 +167,7 @@ View::filter() {
void
View::set_filter_on(int event) {
if (event == DownloadList::SLOTS_INSERT || event == DownloadList::SLOTS_ERASE || event >= DownloadList::SLOTS_MAX_SIZE)
throw torrent::internal_error("View::filter_on(...) invalid event.");
throw torrent::client_error("View::filter_on(...) invalid event.");
m_list->slots(event)["0_view_" + m_name] = sigc::bind(sigc::mem_fun(this, &View::received), event);
}
@ -193,7 +193,7 @@ View::insert_visible(Download* d) {
inline void
View::erase(iterator itr) {
if (itr == end_filtered())
throw torrent::internal_error("View::erase_visible(...) iterator out of range.");
throw torrent::client_error("View::erase_visible(...) iterator out of range.");
m_size -= (itr < end_visible());
m_focus -= (m_focus > position(itr));
@ -209,7 +209,7 @@ View::received(core::Download* download, int event) {
case DownloadList::SLOTS_INSERT:
if (itr != base_type::end())
throw torrent::internal_error("View::received(..., SLOTS_INSERT) already inserted.");
throw torrent::client_error("View::received(..., SLOTS_INSERT) already inserted.");
if (view_downloads_filter(m_filter)(download))
insert_visible(download);
@ -217,7 +217,7 @@ View::received(core::Download* download, int event) {
base_type::insert(end_filtered(), download);
if (m_focus > m_size)
throw torrent::internal_error("View::received(...) m_focus > m_size.");
throw torrent::client_error("View::received(...) m_focus > m_size.");
break;
@ -227,7 +227,7 @@ View::received(core::Download* download, int event) {
default:
if (itr == end_filtered())
throw torrent::internal_error("View::received(..., SLOTS_*) could not find download.");
throw torrent::client_error("View::received(..., SLOTS_*) could not find download.");
if (view_downloads_filter(m_filter)(download)) {

3
src/core/view.h

@ -85,7 +85,8 @@ public:
const std::string& name() const { return m_name; }
bool empty() const { return m_size == 0; }
bool empty_visible() const { return m_size == 0; }
size_type size() const { return m_size; }
// Perhaps this should be renamed?

3
src/core/view_manager.cc

@ -44,7 +44,6 @@
#include "download.h"
#include "download_list.h"
#include "hash_queue.h"
#include "manager.h"
#include "view.h"
#include "view_manager.h"
@ -162,7 +161,7 @@ ViewManager::clear() {
ViewManager::iterator
ViewManager::insert(const std::string& name) {
if (find(name) != end())
throw torrent::internal_error("ViewManager::insert(...) name already inserted.");
throw torrent::client_error("ViewManager::insert(...) name already inserted.");
View* view = new View();
view->initialize(name, m_list);

14
src/display/utils.cc

@ -79,7 +79,7 @@ print_hhmmss_local(char* first, char* last, time_t t) {
if (u == NULL)
//return "inv_time";
throw torrent::internal_error("print_hhmmss_local(...) failed.");
throw torrent::client_error("print_hhmmss_local(...) failed.");
return print_buffer(first, last, "%2u:%02u:%02u", u->tm_hour, u->tm_min, u->tm_sec);
}
@ -98,7 +98,7 @@ print_ddmmyyyy(char* first, char* last, time_t t) {
if (u == NULL)
//return "inv_time";
throw torrent::internal_error("print_ddmmyyyy(...) failed.");
throw torrent::client_error("print_ddmmyyyy(...) failed.");
return print_buffer(first, last, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year));
}
@ -154,17 +154,17 @@ print_download_info(char* first, char* last, core::Download* d) {
first = print_buffer(first, last, " [%s]", core::Download::priority_to_string(d->priority()));
if (first > last)
throw torrent::internal_error("print_download_info(...) wrote past end of the buffer.");
throw torrent::client_error("print_download_info(...) wrote past end of the buffer.");
return first;
}
char*
print_download_status(char* first, char* last, core::Download* d) {
if (!d->download()->is_active())
if (!d->is_active())
first = print_buffer(first, last, "Inactive: ");
if (d->download()->is_hash_checking()) {
if (d->is_hash_checking()) {
first = print_buffer(first, last, "Checking hash [%2i%%]",
(d->download()->chunks_hashed() * 100) / d->download()->chunks_total());
@ -182,7 +182,7 @@ print_download_status(char* first, char* last, core::Download* d) {
}
if (first > last)
throw torrent::internal_error("print_download_status(...) wrote past end of the buffer.");
throw torrent::client_error("print_download_status(...) wrote past end of the buffer.");
return first;
}
@ -233,7 +233,7 @@ print_status_info(char* first, char* last) {
}
if (first > last)
throw torrent::internal_error("print_status_info(...) wrote past end of the buffer.");
throw torrent::client_error("print_status_info(...) wrote past end of the buffer.");
if (!rak::socket_address::cast_from(torrent::connection_manager()->bind_address())->is_address_any()) {
first = print_buffer(first, last, " [Bind ");

2
src/display/window_download_list.cc

@ -73,7 +73,7 @@ WindowDownloadList::redraw() {
m_canvas->print(0, 0, "%s", ("[View: " + m_view->name() + "]").c_str());
if (m_view->empty() || m_canvas->get_width() < 5 || m_canvas->get_height() < 2)
if (m_view->empty_visible() || m_canvas->get_width() < 5 || m_canvas->get_height() < 2)
return;
typedef std::pair<core::View::iterator, core::View::iterator> Range;

6
src/ui/download_list.cc

@ -90,7 +90,7 @@ DownloadList::DownloadList(Control* c) :
receive_change_view("main");
if (m_view == NULL)
throw torrent::internal_error("View \"main\" must be present to initialize the main display.");
throw torrent::client_error("View \"main\" must be present to initialize the main display.");
m_taskUpdate.set_slot(rak::mem_fn(this, &DownloadList::task_update)),
@ -209,7 +209,7 @@ DownloadList::receive_stop_download() {
if (m_view->focus() == m_view->end_visible())
return;
if ((*m_view->focus())->download()->is_active())
if ((*m_view->focus())->variable()->get_value("state") == 1)
m_control->core()->download_list()->stop(*m_view->focus());
else
m_control->core()->download_list()->erase(*m_view->focus());
@ -391,7 +391,7 @@ DownloadList::receive_change_view(const std::string& name) {
ElementDownloadList* ui = dynamic_cast<ElementDownloadList*>(m_uiArray[DISPLAY_DOWNLOAD_LIST]);
if (ui == NULL)
throw torrent::internal_error("DownloadList::receive_change_view(...) could not cast ui.");
throw torrent::client_error("DownloadList::receive_change_view(...) could not cast ui.");
ui->set_view(m_view);
}

12
src/ui/element_file_list.cc

@ -61,7 +61,7 @@ ElementFileList::ElementFileList(core::Download* d) :
void
ElementFileList::activate(Control* c, MItr mItr) {
if (m_window != NULL)
throw torrent::internal_error("ui::ElementFileList::activate(...) called on an object in the wrong state");
throw torrent::client_error("ui::ElementFileList::activate(...) called on an object in the wrong state");
c->input()->push_front(&m_bindings);
@ -71,7 +71,7 @@ ElementFileList::activate(Control* c, MItr mItr) {
void
ElementFileList::disable(Control* c) {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementFileList::disable(...) called on an object in the wrong state");
throw torrent::client_error("ui::ElementFileList::disable(...) called on an object in the wrong state");
c->input()->erase(&m_bindings);
@ -82,7 +82,7 @@ ElementFileList::disable(Control* c) {
void
ElementFileList::receive_next() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementFileList::receive_next(...) called on a disabled object");
throw torrent::client_error("ui::ElementFileList::receive_next(...) called on a disabled object");
if (++m_focus >= m_download->download()->file_list().size())
m_focus = 0;
@ -93,7 +93,7 @@ ElementFileList::receive_next() {
void
ElementFileList::receive_prev() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
throw torrent::client_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
torrent::FileList fl = m_download->download()->file_list();
@ -111,7 +111,7 @@ ElementFileList::receive_prev() {
void
ElementFileList::receive_priority() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
throw torrent::client_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
torrent::FileList fl = m_download->download()->file_list();
@ -129,7 +129,7 @@ ElementFileList::receive_priority() {
void
ElementFileList::receive_change_all() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
throw torrent::client_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
torrent::FileList fl = m_download->download()->file_list();

14
src/ui/element_tracker_list.cc

@ -62,7 +62,7 @@ ElementTrackerList::ElementTrackerList(core::Download* d) :
void
ElementTrackerList::activate(Control* c, MItr mItr) {
if (m_window != NULL)
throw torrent::internal_error("ui::ElementTrackerList::activate(...) called on an object in the wrong state");
throw torrent::client_error("ui::ElementTrackerList::activate(...) called on an object in the wrong state");
c->input()->push_front(&m_bindings);
@ -72,7 +72,7 @@ ElementTrackerList::activate(Control* c, MItr mItr) {
void
ElementTrackerList::disable(Control* c) {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementTrackerList::disable(...) called on an object in the wrong state");
throw torrent::client_error("ui::ElementTrackerList::disable(...) called on an object in the wrong state");
c->input()->erase(&m_bindings);
@ -83,7 +83,7 @@ ElementTrackerList::disable(Control* c) {
void
ElementTrackerList::receive_disable() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementTrackerList::receive_disable(...) called on a disabled object");
throw torrent::client_error("ui::ElementTrackerList::receive_disable(...) called on a disabled object");
torrent::Tracker t = m_download->download()->tracker_list().get(m_focus);
@ -98,7 +98,7 @@ ElementTrackerList::receive_disable() {
void
ElementTrackerList::receive_next() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementTrackerList::receive_next(...) called on a disabled object");
throw torrent::client_error("ui::ElementTrackerList::receive_next(...) called on a disabled object");
if (++m_focus >= m_download->download()->tracker_list().size())
m_focus = 0;
@ -109,7 +109,7 @@ ElementTrackerList::receive_next() {
void
ElementTrackerList::receive_prev() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementTrackerList::receive_prev(...) called on a disabled object");
throw torrent::client_error("ui::ElementTrackerList::receive_prev(...) called on a disabled object");
if (m_download->download()->tracker_list().size() == 0)
return;
@ -125,12 +125,12 @@ ElementTrackerList::receive_prev() {
void
ElementTrackerList::receive_cycle_group() {
if (m_window == NULL)
throw torrent::internal_error("ui::ElementTrackerList::receive_group_cycle(...) called on a disabled object");
throw torrent::client_error("ui::ElementTrackerList::receive_group_cycle(...) called on a disabled object");
torrent::TrackerList tl = m_download->download()->tracker_list();
if (m_focus >= tl.size())
throw torrent::internal_error("ui::ElementTrackerList::receive_group_cycle(...) called with an invalid focus");
throw torrent::client_error("ui::ElementTrackerList::receive_group_cycle(...) called with an invalid focus");
tl.cycle_group(tl.get(m_focus).group());

2
src/utils/variable_map.cc

@ -59,7 +59,7 @@ VariableMap::insert(const std::string& key, Variable* v) {
iterator itr = base_type::find(key);
if (itr != base_type::end())
throw torrent::internal_error("VariableMap::insert(...) tried to insert an already existing key.");
throw torrent::client_error("VariableMap::insert(...) tried to insert an already existing key.");
base_type::insert(itr, value_type(key, v));
}

Loading…
Cancel
Save