mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-17 23:52:30 +00:00
* Moved hash and torrent size checking to initialize so it will be
caught when loading a torrent. * Added VariableMap to core::Download and started moving various settings. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@624 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
AC_INIT(rtorrent, 0.4.2, jaris@ifi.uio.no)
|
||||
AC_INIT(rtorrent, 0.4.3, jaris@ifi.uio.no)
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
+6
-5
@@ -321,14 +321,10 @@ bind1st(const Operation& op, const Type& val) {
|
||||
template <typename Operation>
|
||||
class bind2nd_t : public std::unary_function<typename Operation::first_argument_type,
|
||||
typename Operation::result_type> {
|
||||
protected:
|
||||
public:
|
||||
typedef typename reference_fix<typename Operation::first_argument_type>::type argument_type;
|
||||
typedef typename reference_fix<typename Operation::second_argument_type>::type value_type;
|
||||
|
||||
Operation m_op;
|
||||
value_type m_value;
|
||||
|
||||
public:
|
||||
bind2nd_t(const Operation& op, const value_type v) :
|
||||
m_op(op), m_value(v) {}
|
||||
|
||||
@@ -336,6 +332,11 @@ public:
|
||||
operator () (const argument_type arg) {
|
||||
return m_op(arg, m_value);
|
||||
}
|
||||
|
||||
protected:
|
||||
Operation m_op;
|
||||
value_type m_value;
|
||||
|
||||
};
|
||||
|
||||
template <typename Operation, typename Type>
|
||||
|
||||
@@ -180,6 +180,20 @@ private:
|
||||
const Arg1 m_arg1;
|
||||
};
|
||||
|
||||
template <typename Result, typename Arg1>
|
||||
class ptr_fn1_t : public function_base1<Result, Arg1> {
|
||||
public:
|
||||
typedef Result (*Func)(Arg1);
|
||||
|
||||
ptr_fn1_t(Func func) : m_func(func) {}
|
||||
virtual ~ptr_fn1_t() {}
|
||||
|
||||
virtual Result operator () (Arg1 arg1) { return m_func(arg1); }
|
||||
|
||||
private:
|
||||
Func m_func;
|
||||
};
|
||||
|
||||
template <typename Result, typename Arg1, typename Arg2>
|
||||
class ptr_fn1_b1_t : public function_base1<Result, Arg2> {
|
||||
public:
|
||||
@@ -225,6 +239,12 @@ bind_mem_fn(Object* object, Result (Object::*func)(Arg1), const Arg1 arg1) {
|
||||
return new mem_fn0_b1_t<Object, Result, Arg1>(object, func, arg1);
|
||||
}
|
||||
|
||||
template <typename Result, typename Arg1>
|
||||
function_base1<Result, Arg1>*
|
||||
ptr_fn(Result (*func)(Arg1)) {
|
||||
return new ptr_fn1_t<Result, Arg1>(func);
|
||||
}
|
||||
|
||||
template <typename Result, typename Arg1, typename Arg2>
|
||||
function_base1<Result, Arg2>*
|
||||
bind_ptr_fn(Result (*func)(Arg1, Arg2), const Arg1 arg1) {
|
||||
|
||||
+29
-13
@@ -42,6 +42,8 @@
|
||||
#include <sigc++/signal.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "utils/variable_generic.h"
|
||||
|
||||
#include "download.h"
|
||||
|
||||
namespace core {
|
||||
@@ -49,15 +51,25 @@ namespace core {
|
||||
Download::Download(torrent::Download d) :
|
||||
m_download(d),
|
||||
|
||||
m_chunksFailed(0),
|
||||
m_connectionLeech(torrent::Download::CONNECTION_LEECH),
|
||||
m_connectionSeed(torrent::Download::CONNECTION_SEED) {
|
||||
m_chunksFailed(0) {
|
||||
|
||||
m_connTrackerSucceded = m_download.signal_tracker_succeded(sigc::bind(sigc::mem_fun(*this, &Download::receive_tracker_msg), ""));
|
||||
m_connTrackerFailed = m_download.signal_tracker_failed(sigc::mem_fun(*this, &Download::receive_tracker_msg));
|
||||
m_connStorageError = m_download.signal_storage_error(sigc::mem_fun(*this, &Download::receive_storage_error));
|
||||
|
||||
m_download.signal_chunk_failed(sigc::mem_fun(*this, &Download::receive_chunk_failed));
|
||||
|
||||
m_variables.insert("connection_current", new utils::VariableSlotString<const char*, const std::string&>(rak::mem_fn(this, &Download::connection_current),
|
||||
rak::mem_fn(this, &Download::set_connection_current)));
|
||||
m_variables.insert("connection_leech", new utils::VariableValue(connection_type_to_string(torrent::Download::CONNECTION_LEECH)));
|
||||
m_variables.insert("connection_seed", new utils::VariableValue(connection_type_to_string(torrent::Download::CONNECTION_SEED)));
|
||||
m_variables.insert("directory", new utils::VariableSlotString<std::string, const std::string&>(NULL,
|
||||
rak::mem_fn(this, &Download::set_root_directory)));
|
||||
m_variables.insert("tied_to_file", new utils::VariableBencode(&m_download.bencode(), "tied_to_file", torrent::Bencode::TYPE_STRING));
|
||||
|
||||
m_variables.insert("peers_min", new utils::VariableSlotValue<uint32_t, uint32_t>(rak::mem_fn(&m_download, &torrent::Download::peers_min),
|
||||
rak::mem_fn(&m_download, &torrent::Download::set_peers_min),
|
||||
"%u"));
|
||||
}
|
||||
|
||||
Download::~Download() {
|
||||
@@ -74,23 +86,16 @@ Download::~Download() {
|
||||
void
|
||||
Download::start() {
|
||||
if (is_done()) {
|
||||
m_download.set_connection_type(m_connectionSeed);
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_seed").as_string()));
|
||||
torrent::download_set_priority(m_download, 2);
|
||||
} else {
|
||||
m_download.set_connection_type(m_connectionLeech);
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_leech").as_string()));
|
||||
torrent::download_set_priority(m_download, 4);
|
||||
}
|
||||
|
||||
m_download.start();
|
||||
}
|
||||
|
||||
void
|
||||
Download::set_root_directory(const std::string& d) {
|
||||
m_download.set_root_dir(d +
|
||||
(!d.empty() && *d.rbegin() != '/' ? "/" : "") +
|
||||
(m_download.size_file_entries() > 1 ? m_download.name() : ""));
|
||||
}
|
||||
|
||||
void
|
||||
Download::enable_udp_trackers(bool state) {
|
||||
for (int i = 0, last = m_download.size_trackers(); i < last; ++i)
|
||||
@@ -103,7 +108,7 @@ Download::enable_udp_trackers(bool state) {
|
||||
|
||||
void
|
||||
Download::receive_finished() {
|
||||
m_download.set_connection_type(m_connectionSeed);
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_seed").as_string()));
|
||||
torrent::download_set_priority(m_download, 2);
|
||||
}
|
||||
|
||||
@@ -148,4 +153,15 @@ Download::receive_chunk_failed(uint32_t idx) {
|
||||
m_chunksFailed++;
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
void
|
||||
Download::set_root_directory(const std::string& d) {
|
||||
if (d.empty())
|
||||
m_download.set_root_dir("./" + (m_download.size_file_entries() > 1 ? m_download.name() : std::string()));
|
||||
else
|
||||
m_download.set_root_dir(d +
|
||||
(*d.rbegin() != '/' ? "/" : "") +
|
||||
(m_download.size_file_entries() > 1 ? m_download.name() : ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-17
@@ -41,6 +41,8 @@
|
||||
#include <torrent/download.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#include "utils/variable_map.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class Download {
|
||||
@@ -55,6 +57,9 @@ public:
|
||||
|
||||
void start();
|
||||
|
||||
utils::VariableMap* variables() { return &m_variables; }
|
||||
std::string variable_string(const std::string& key) { return m_variables.get_string(key); }
|
||||
|
||||
torrent::Download& get_download() { return m_download; }
|
||||
const torrent::Download& get_download() const { return m_download; }
|
||||
std::string get_hash() { return m_download.info_hash(); }
|
||||
@@ -64,18 +69,6 @@ public:
|
||||
|
||||
uint32_t chunks_failed() const { return m_chunksFailed; }
|
||||
|
||||
void set_root_directory(const std::string& d);
|
||||
|
||||
ConnType get_connection_current() const { return m_download.connection_type(); }
|
||||
ConnType get_connection_leech() const { return m_connectionLeech; }
|
||||
ConnType get_connection_seed() const { return m_connectionSeed; }
|
||||
|
||||
void set_connection_leech(const std::string& name) { m_connectionLeech = string_to_connection_type(name); }
|
||||
void set_connection_seed(const std::string& name) { m_connectionSeed = string_to_connection_type(name); }
|
||||
|
||||
const std::string& tied_to_file() const { return m_tiedToFile; }
|
||||
void set_tied_to_file(const std::string& str) { m_tiedToFile = str; }
|
||||
|
||||
void enable_udp_trackers(bool state);
|
||||
|
||||
// Helper functions for calling functions in torrent::Download
|
||||
@@ -94,24 +87,29 @@ public:
|
||||
static const char* connection_type_to_string(ConnType t);
|
||||
|
||||
private:
|
||||
Download(const Download&);
|
||||
void operator () (const Download&);
|
||||
|
||||
void receive_tracker_msg(std::string msg);
|
||||
void receive_storage_error(std::string msg);
|
||||
|
||||
void receive_chunk_failed(uint32_t idx);
|
||||
|
||||
const char* connection_current() const { return connection_type_to_string(m_download.connection_type()); }
|
||||
void set_connection_current(const std::string& t) { return m_download.set_connection_type(string_to_connection_type(t.c_str())); }
|
||||
|
||||
void set_root_directory(const std::string& d);
|
||||
|
||||
torrent::Download m_download;
|
||||
|
||||
std::string m_message;
|
||||
uint32_t m_chunksFailed;
|
||||
|
||||
ConnType m_connectionLeech;
|
||||
ConnType m_connectionSeed;
|
||||
|
||||
std::string m_tiedToFile;
|
||||
|
||||
sigc::connection m_connTrackerSucceded;
|
||||
sigc::connection m_connTrackerFailed;
|
||||
sigc::connection m_connStorageError;
|
||||
|
||||
utils::VariableMap m_variables;
|
||||
};
|
||||
|
||||
inline bool
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
#include <torrent/bencode.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "utils/variable_generic.h"
|
||||
|
||||
#include "curl_get.h"
|
||||
#include "http_queue.h"
|
||||
#include "globals.h"
|
||||
@@ -60,12 +62,16 @@ DownloadFactory::DownloadFactory(const std::string& uri, Manager* m) :
|
||||
m_uri(uri),
|
||||
m_session(false),
|
||||
m_start(false),
|
||||
m_printLog(true),
|
||||
m_tiedToFile(false) {
|
||||
m_printLog(true) {
|
||||
|
||||
m_taskLoad.set_slot(rak::mem_fn(this, &DownloadFactory::receive_load));
|
||||
m_taskCommit.set_slot(rak::mem_fn(this, &DownloadFactory::receive_commit));
|
||||
}
|
||||
|
||||
m_variables.insert("connection_leech", new utils::VariableValue(control->variables()->get("connection_leech")));
|
||||
m_variables.insert("connection_seed", new utils::VariableValue(control->variables()->get("connection_seed")));
|
||||
m_variables.insert("directory", new utils::VariableValue(control->variables()->get("directory")));
|
||||
m_variables.insert("tied_to_file", new utils::VariableBool(false));
|
||||
}
|
||||
|
||||
DownloadFactory::~DownloadFactory() {
|
||||
priority_queue_erase(&taskScheduler, &m_taskLoad);
|
||||
@@ -98,7 +104,7 @@ DownloadFactory::receive_load() {
|
||||
(*itr)->signal_done().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_loaded));
|
||||
(*itr)->signal_failed().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_failed));
|
||||
|
||||
m_tiedToFile = false;
|
||||
m_variables.set("tied_to_file", (int64_t)false);
|
||||
|
||||
} else {
|
||||
m_stream = new std::fstream(m_uri.c_str(), std::ios::in);
|
||||
@@ -140,6 +146,14 @@ DownloadFactory::receive_success() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move to 'rtorrent'.
|
||||
(*itr)->variables()->set("connection_leech", m_variables.get("connection_leech"));
|
||||
(*itr)->variables()->set("connection_seed", m_variables.get("connection_seed"));
|
||||
(*itr)->variables()->set("directory", m_variables.get("directory"));
|
||||
|
||||
// if (control->variables()->get("peers_min")
|
||||
// (*itr)->variables()->set("peers_min", m_variables.get("directory"));
|
||||
|
||||
torrent::Bencode& bencode = (*itr)->get_bencode();
|
||||
|
||||
if (m_session) {
|
||||
@@ -147,18 +161,16 @@ DownloadFactory::receive_success() {
|
||||
if (bencode.get_key("rtorrent").get_key("state").as_string() == "started")
|
||||
m_manager->start(*itr, m_printLog);
|
||||
|
||||
if (bencode.get_key("rtorrent").has_key("tied") &&
|
||||
bencode.get_key("rtorrent").get_key("tied").is_string())
|
||||
(*itr)->set_tied_to_file(bencode.get_key("rtorrent").get_key("tied").as_string());
|
||||
// Consider adding an empty 'tied_to_file' here if not present.
|
||||
|
||||
} else {
|
||||
// Remove the settings if this isn't a session torrent.
|
||||
//bencode.erase_key("rtorrent");
|
||||
|
||||
if (m_tiedToFile) {
|
||||
(*itr)->set_tied_to_file(m_uri);
|
||||
bencode.get_key("rtorrent").insert_key("tied", m_uri);
|
||||
}
|
||||
if (m_variables.get("tied_to_file").as_value())
|
||||
(*itr)->variables()->set("tied_to_file", m_uri);
|
||||
else
|
||||
(*itr)->variables()->set("tied_to_file", std::string());
|
||||
|
||||
if (m_start)
|
||||
m_manager->start(*itr, m_printLog);
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include <sigc++/slot.h>
|
||||
#include <rak/priority_queue_default.h>
|
||||
|
||||
#include "utils/variable_map.h"
|
||||
|
||||
#include "http_queue.h"
|
||||
|
||||
namespace core {
|
||||
@@ -65,6 +67,8 @@ public:
|
||||
void load();
|
||||
void commit();
|
||||
|
||||
utils::VariableMap* variables() { return &m_variables; }
|
||||
|
||||
bool get_session() const { return m_session; }
|
||||
void set_session(bool v) { m_session = v; }
|
||||
|
||||
@@ -74,9 +78,6 @@ public:
|
||||
bool print_log() const { return m_printLog; }
|
||||
void set_print_log(bool v) { m_printLog = v; }
|
||||
|
||||
bool tied_to_file() const { return m_tiedToFile; }
|
||||
void set_tied_to_file(bool v) { m_tiedToFile = v; }
|
||||
|
||||
void slot_finished(Slot s) { m_slotFinished = s; }
|
||||
|
||||
private:
|
||||
@@ -96,7 +97,8 @@ private:
|
||||
bool m_session;
|
||||
bool m_start;
|
||||
bool m_printLog;
|
||||
bool m_tiedToFile;
|
||||
|
||||
utils::VariableMap m_variables;
|
||||
|
||||
Slot m_slotFinished;
|
||||
rak::priority_item m_taskLoad;
|
||||
|
||||
+7
-4
@@ -80,10 +80,12 @@ connect_signal_storage_log(Download* d, torrent::Download::SlotString s) {
|
||||
// Hmm... find some better place for all this.
|
||||
static void
|
||||
delete_tied(Download* d) {
|
||||
const std::string tie = d->variables()->get("tied_to_file").as_string();
|
||||
|
||||
// This should be configurable, need to wait for the variable
|
||||
// thingie to be implemented.
|
||||
if (!d->tied_to_file().empty())
|
||||
::unlink(d->tied_to_file().c_str());
|
||||
if (!tie.empty())
|
||||
::unlink(tie.c_str());
|
||||
}
|
||||
|
||||
Manager::Manager() :
|
||||
@@ -338,9 +340,10 @@ Manager::try_create_download(const std::string& uri, bool start, bool printLog,
|
||||
// Adding download.
|
||||
DownloadFactory* f = new DownloadFactory(uri, this);
|
||||
|
||||
f->variables()->set("tied_to_file", tied ? "yes" : "no");
|
||||
|
||||
f->set_start(start);
|
||||
f->set_print_log(printLog);
|
||||
f->set_tied_to_file(tied);
|
||||
f->slot_finished(sigc::bind(sigc::ptr_fun(&rak::call_delete_func<core::DownloadFactory>), f));
|
||||
f->load();
|
||||
f->commit();
|
||||
@@ -402,7 +405,7 @@ Manager::try_create_download_expand(const std::string& uri, bool start, bool pri
|
||||
if (tied)
|
||||
for (std::vector<std::string>::iterator itr = paths.begin(); itr != paths.end(); )
|
||||
if (std::find_if(m_downloadList.begin(), m_downloadList.end(),
|
||||
rak::equal(*itr, std::mem_fun(&Download::tied_to_file))) != m_downloadList.end())
|
||||
rak::equal(*itr, rak::bind2nd(std::mem_fun(&Download::variable_string), "tied_to_file"))) != m_downloadList.end())
|
||||
itr = paths.erase(itr);
|
||||
else
|
||||
itr++;
|
||||
|
||||
@@ -80,11 +80,11 @@ WindowPeerInfo::redraw() {
|
||||
y++;
|
||||
|
||||
m_canvas->print(0, y++, "Connection Type: %s ( %s / %s )",
|
||||
core::Download::connection_type_to_string(m_download->get_connection_current()),
|
||||
core::Download::connection_type_to_string(m_download->get_connection_leech()),
|
||||
core::Download::connection_type_to_string(m_download->get_connection_seed()));
|
||||
m_canvas->print(0, y++, "Tied to file: %s",
|
||||
m_download->tied_to_file().c_str());
|
||||
m_download->variables()->get("connection_current").as_string().c_str(),
|
||||
m_download->variables()->get("connection_seed").as_string().c_str(),
|
||||
m_download->variables()->get("connection_leech").as_string().c_str());
|
||||
|
||||
m_canvas->print(0, y++, "Tied to file: %s", m_download->variable_string("tied_to_file").c_str());
|
||||
|
||||
y++;
|
||||
|
||||
|
||||
+17
-44
@@ -103,26 +103,6 @@ apply_download_max_uploads(Control* m, int arg) {
|
||||
m->core()->get_download_list().slot_map_insert()["1_max_uploads"] = sigc::bind(sigc::mem_fun(&core::Download::call<void, uint32_t, &torrent::Download::set_uploads_max>), arg);
|
||||
}
|
||||
|
||||
void
|
||||
apply_download_directory(Control* m, const std::string& arg) {
|
||||
if (!arg.empty())
|
||||
m->core()->get_download_list().slot_map_insert()["1_directory"] = sigc::bind(sigc::mem_fun(&core::Download::set_root_directory), arg);
|
||||
else
|
||||
m->core()->get_download_list().slot_map_insert().erase("1_directory");
|
||||
}
|
||||
|
||||
void
|
||||
apply_connection_leech(Control* m, const std::string& arg) {
|
||||
core::Download::string_to_connection_type(arg);
|
||||
m->core()->get_download_list().slot_map_insert()["1_connection_leech"] = sigc::bind(sigc::mem_fun(&core::Download::set_connection_leech), arg);
|
||||
}
|
||||
|
||||
void
|
||||
apply_connection_seed(Control* m, const std::string& arg) {
|
||||
core::Download::string_to_connection_type(arg);
|
||||
m->core()->get_download_list().slot_map_insert()["1_connection_seed"] = sigc::bind(sigc::mem_fun(&core::Download::set_connection_seed), arg);
|
||||
}
|
||||
|
||||
void
|
||||
apply_global_download_rate(Control* m, int arg) {
|
||||
m->ui()->set_down_throttle(arg);
|
||||
@@ -134,7 +114,7 @@ apply_global_upload_rate(Control* m, int arg) {
|
||||
}
|
||||
|
||||
void
|
||||
apply_umask(Control* m, int arg) {
|
||||
apply_umask(int arg) {
|
||||
umask(arg);
|
||||
}
|
||||
|
||||
@@ -163,11 +143,6 @@ apply_max_open_sockets(Control* m, int arg) {
|
||||
torrent::set_max_open_sockets(arg);
|
||||
}
|
||||
|
||||
void
|
||||
apply_ip(Control* m, const std::string& arg) {
|
||||
torrent::set_local_address(arg);
|
||||
}
|
||||
|
||||
// The arg string *must* have been checked with validate_port_range
|
||||
// first.
|
||||
void
|
||||
@@ -215,14 +190,13 @@ apply_stop_untied(Control* m, const std::string& arg) {
|
||||
core::Manager::DListItr itr = m->core()->get_download_list().begin();
|
||||
|
||||
while ((itr = std::find_if(itr, m->core()->get_download_list().end(),
|
||||
rak::on(std::mem_fun(&core::Download::tied_to_file), std::not1(std::mem_fun_ref(&std::string::empty)))))
|
||||
rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"),
|
||||
std::not1(std::mem_fun_ref(&std::string::empty)))))
|
||||
!= m->core()->get_download_list().end()) {
|
||||
rak::file_stat fs;
|
||||
|
||||
if (!fs.update((*itr)->tied_to_file())) {
|
||||
(*itr)->set_tied_to_file(std::string());
|
||||
(*itr)->get_bencode().get_key("rtorrent").erase_key("tied");
|
||||
|
||||
if (!fs.update((*itr)->variable_string("tied_to_file"))) {
|
||||
(*itr)->variables()->set("tied_to_file", std::string());
|
||||
m->core()->stop(*itr);
|
||||
}
|
||||
|
||||
@@ -235,14 +209,13 @@ apply_remove_untied(Control* m, const std::string& arg) {
|
||||
core::Manager::DListItr itr = m->core()->get_download_list().begin();
|
||||
|
||||
while ((itr = std::find_if(itr, m->core()->get_download_list().end(),
|
||||
rak::on(std::mem_fun(&core::Download::tied_to_file), std::not1(std::mem_fun_ref(&std::string::empty)))))
|
||||
rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"),
|
||||
std::not1(std::mem_fun_ref(&std::string::empty)))))
|
||||
!= m->core()->get_download_list().end()) {
|
||||
rak::file_stat fs;
|
||||
|
||||
if (!fs.update((*itr)->tied_to_file())) {
|
||||
(*itr)->set_tied_to_file(std::string());
|
||||
(*itr)->get_bencode().get_key("rtorrent").erase_key("tied");
|
||||
|
||||
if (!fs.update((*itr)->variable_string("tied_to_file"))) {
|
||||
(*itr)->variables()->set("tied_to_file", std::string());
|
||||
m->core()->stop(*itr);
|
||||
itr = m->core()->erase(itr);
|
||||
|
||||
@@ -294,15 +267,18 @@ initialize_option_handler(Control* c) {
|
||||
variables->insert("port_random", new utils::VariableValue("yes"));
|
||||
variables->insert("session", new utils::VariableSlotString<>(NULL, rak::mem_fn(&control->core()->get_download_store(), &core::DownloadStore::use)));
|
||||
|
||||
variables->insert("connection_leech", new utils::VariableValue("leech"));
|
||||
variables->insert("connection_seed", new utils::VariableValue("seed"));
|
||||
|
||||
variables->insert("directory", new utils::VariableValue(std::string()));
|
||||
variables->insert("ip", new utils::VariableSlotString<>(NULL, rak::ptr_fn(&torrent::set_local_address)));
|
||||
|
||||
// Old.
|
||||
variables->insert("bind", new utils::VariableSlotString<>(NULL, rak::mem_fn(control->core(), &core::Manager::bind)));
|
||||
|
||||
variables->insert("ip", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_ip, c)));
|
||||
variables->insert("port_range", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_range, c)));
|
||||
|
||||
variables->insert("directory", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_download_directory, c)));
|
||||
|
||||
variables->insert("max_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_peers, c), "%i"));
|
||||
|
||||
variables->insert("min_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_min_peers, c), "%i"));
|
||||
variables->insert("max_uploads", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_uploads, c), "%i"));
|
||||
|
||||
@@ -315,10 +291,7 @@ initialize_option_handler(Control* c) {
|
||||
variables->insert("max_open_files", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_max_open_files, c), "%i"));
|
||||
variables->insert("max_open_sockets", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_max_open_sockets, c), "%i"));
|
||||
|
||||
variables->insert("umask", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_umask, c), "%o"));
|
||||
|
||||
variables->insert("connection_leech", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_leech, c)));
|
||||
variables->insert("connection_seed", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_seed, c)));
|
||||
variables->insert("umask", new utils::VariableSlotValue<int, int>(NULL, rak::ptr_fn(&apply_umask), "%o"));
|
||||
|
||||
variables->insert("load", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load, c)));
|
||||
variables->insert("load_start", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load_start, c)));
|
||||
|
||||
@@ -53,4 +53,65 @@ VariableValue::set(const torrent::Bencode& arg) {
|
||||
m_variable = arg;
|
||||
}
|
||||
|
||||
VariableBool::~VariableBool() {
|
||||
}
|
||||
|
||||
const torrent::Bencode&
|
||||
VariableBool::get() {
|
||||
return m_variable;
|
||||
}
|
||||
|
||||
void
|
||||
VariableBool::set(const torrent::Bencode& arg) {
|
||||
if (arg.is_value()) {
|
||||
m_variable = arg.as_value() ? (int64_t)1 : (int64_t)0;
|
||||
|
||||
} else if (arg.is_string()) {
|
||||
|
||||
if (arg.as_string() == "yes" ||
|
||||
arg.as_string() == "true")
|
||||
m_variable = (int64_t)1;
|
||||
|
||||
else if (arg.as_string() == "no" ||
|
||||
arg.as_string() == "false")
|
||||
m_variable = (int64_t)0;
|
||||
|
||||
else
|
||||
throw torrent::input_error("String does not parse as a boolean.");
|
||||
|
||||
} else {
|
||||
throw torrent::input_error("Input is not a boolean.");
|
||||
}
|
||||
}
|
||||
|
||||
VariableBencode::~VariableBencode() {
|
||||
}
|
||||
|
||||
const torrent::Bencode&
|
||||
VariableBencode::get() {
|
||||
return m_bencode->get_key(m_key);
|
||||
}
|
||||
|
||||
void
|
||||
VariableBencode::set(const torrent::Bencode& arg) {
|
||||
// Consider removing if TYPE_NONE.
|
||||
|
||||
switch (m_type) {
|
||||
case torrent::Bencode::TYPE_NONE:
|
||||
m_bencode->insert_key(m_key, arg);
|
||||
break;
|
||||
|
||||
case torrent::Bencode::TYPE_STRING:
|
||||
if (arg.get_type() == torrent::Bencode::TYPE_STRING)
|
||||
m_bencode->insert_key(m_key, arg);
|
||||
else
|
||||
throw torrent::input_error("VariableBencode could not convert to string.");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw torrent::input_error("VariableBencode unsupported type restriction.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,6 +61,36 @@ private:
|
||||
torrent::Bencode m_variable;
|
||||
};
|
||||
|
||||
class VariableBool : public Variable {
|
||||
public:
|
||||
VariableBool(bool state) : m_variable(state ? (int64_t)1 : (int64_t)0) {}
|
||||
VariableBool(const torrent::Bencode& v = torrent::Bencode((int64_t)0)) { set(v); }
|
||||
virtual ~VariableBool();
|
||||
|
||||
virtual const torrent::Bencode& get();
|
||||
virtual void set(const torrent::Bencode& arg);
|
||||
|
||||
private:
|
||||
torrent::Bencode m_variable;
|
||||
};
|
||||
|
||||
class VariableBencode : public Variable {
|
||||
public:
|
||||
typedef torrent::Bencode::Type Type;
|
||||
|
||||
VariableBencode(torrent::Bencode* b, const std::string& key, Type t = torrent::Bencode::TYPE_NONE) :
|
||||
m_bencode(b), m_key(key), m_type(t) {}
|
||||
virtual ~VariableBencode();
|
||||
|
||||
virtual const torrent::Bencode& get();
|
||||
virtual void set(const torrent::Bencode& arg);
|
||||
|
||||
private:
|
||||
torrent::Bencode* m_bencode;
|
||||
std::string m_key;
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
template <typename Get = std::string, typename Set = const std::string&>
|
||||
class VariableSlotString : public Variable {
|
||||
public:
|
||||
|
||||
@@ -60,7 +60,7 @@ VariableMap::insert(const std::string& key, Variable* v) {
|
||||
base_type::insert(itr, value_type(key, v));
|
||||
}
|
||||
|
||||
const torrent::Bencode&
|
||||
const VariableMap::mapped_type&
|
||||
VariableMap::get(const std::string& key) {
|
||||
iterator itr = base_type::find(key);
|
||||
|
||||
@@ -71,7 +71,7 @@ VariableMap::get(const std::string& key) {
|
||||
}
|
||||
|
||||
void
|
||||
VariableMap::set(const std::string& key, const torrent::Bencode& arg) {
|
||||
VariableMap::set(const std::string& key, const mapped_type& arg) {
|
||||
iterator itr = base_type::find(key);
|
||||
|
||||
// Later, allow the user to create new variables. Have a slot to
|
||||
@@ -94,7 +94,7 @@ parse_name(std::string::const_iterator first, std::string::const_iterator last,
|
||||
}
|
||||
|
||||
std::string::const_iterator
|
||||
parse_unknown(std::string::const_iterator first, std::string::const_iterator last, torrent::Bencode* dest) {
|
||||
parse_unknown(std::string::const_iterator first, std::string::const_iterator last, VariableMap::mapped_type* dest) {
|
||||
if (*first == '"') {
|
||||
std::string::const_iterator next = std::find_if(++first, last, std::bind2nd(std::equal_to<char>(), '"'));
|
||||
|
||||
@@ -116,11 +116,11 @@ parse_unknown(std::string::const_iterator first, std::string::const_iterator las
|
||||
}
|
||||
|
||||
std::string::const_iterator
|
||||
parse_args(std::string::const_iterator first, std::string::const_iterator last, torrent::Bencode::List* dest) {
|
||||
parse_args(std::string::const_iterator first, std::string::const_iterator last, VariableMap::mapped_type::List* dest) {
|
||||
first = std::find_if(first, last, std::not1(std::ptr_fun(&std::isspace)));
|
||||
|
||||
while (first != last) {
|
||||
dest->push_back(torrent::Bencode());
|
||||
dest->push_back(VariableMap::mapped_type());
|
||||
|
||||
first = parse_unknown(first, last, &dest->back());
|
||||
first = std::find_if(first, last, std::not1(std::ptr_fun(&std::isspace)));
|
||||
@@ -148,11 +148,11 @@ VariableMap::process_command(const std::string& command) {
|
||||
if (pos == command.end() || *pos != '=')
|
||||
throw torrent::input_error("Could not find '='.");
|
||||
|
||||
torrent::Bencode args(torrent::Bencode::TYPE_LIST);
|
||||
mapped_type args(mapped_type::TYPE_LIST);
|
||||
parse_args(pos + 1, command.end(), &args.as_list());
|
||||
|
||||
if (args.as_list().empty())
|
||||
set(key, torrent::Bencode());
|
||||
set(key, mapped_type());
|
||||
|
||||
else if (++args.as_list().begin() == args.as_list().end())
|
||||
set(key, *args.as_list().begin());
|
||||
|
||||
@@ -48,6 +48,7 @@ class Variable;
|
||||
class VariableMap : public std::map<std::string, Variable*> {
|
||||
public:
|
||||
typedef std::map<std::string, Variable*> base_type;
|
||||
typedef torrent::Bencode mapped_type;
|
||||
|
||||
using base_type::iterator;
|
||||
using base_type::value_type;
|
||||
@@ -59,10 +60,11 @@ public:
|
||||
|
||||
// Consider taking char* start and finish instead of std::string to
|
||||
// avoid copying. Or make a view class.
|
||||
const torrent::Bencode& get(const std::string& key);
|
||||
const mapped_type& get(const std::string& key);
|
||||
std::string get_string(const std::string& key);
|
||||
|
||||
void set(const std::string& key, const torrent::Bencode& arg);
|
||||
void set_string(const std::string& key, const std::string& arg) { set(key, torrent::Bencode(arg)); }
|
||||
void set(const std::string& key, const mapped_type& arg);
|
||||
void set_string(const std::string& key, const std::string& arg) { set(key, mapped_type(arg)); }
|
||||
|
||||
// Temporary.
|
||||
void process_command(const std::string& command);
|
||||
@@ -72,6 +74,16 @@ private:
|
||||
void operator = (const VariableMap&);
|
||||
};
|
||||
|
||||
inline std::string
|
||||
VariableMap::get_string(const std::string& key) {
|
||||
const mapped_type& v = get(key);
|
||||
|
||||
if (v.get_type() == mapped_type::TYPE_NONE)
|
||||
return std::string();
|
||||
else
|
||||
return v.as_string();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user