From b301faf3cad3d610ae98ac0f829554ee0c66ccc8 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sat, 20 Jan 2007 12:42:14 +0000 Subject: [PATCH] * Fixed a leaking rak::address_info in TrackerUdp. Patch by Josef Drexler. * Finished converting the variables in core::Download to use the new get/set_d(core::Download, ...) functions. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@848 e378c898-3ddf-0310-93e7-cc216c733640 --- src/core/download.cc | 57 +++++++++------ src/utils/variable_generic.cc | 105 +++++++++++++++------------- src/utils/variable_generic.h | 128 ++++++++++++++++++++++++---------- 3 files changed, 186 insertions(+), 104 deletions(-) diff --git a/src/core/download.cc b/src/core/download.cc index c3b55018..38548a6b 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -54,6 +54,26 @@ namespace core { +template +utils::Variable* +var_d_value(Target target, GetFunc getFunc, SetFunc setFunc) { + return new utils::VariableDownloadValueSlot(rak::ftor_fn1(rak::on(std::mem_fun(target), std::mem_fun(getFunc))), + rak::ftor_fn2(rak::on2(std::mem_fun(target), std::mem_fun(setFunc)))); +} + +template +utils::Variable* +var_d2_value(Target target, GetFunc getFunc, SetFunc setFunc) { + return new utils::VariableDownloadValueSlot(rak::ftor_fn1(rak::on(rak::on(std::mem_fun(&Download::download), std::mem_fun(target)), std::mem_fun(getFunc))), + rak::ftor_fn2(rak::on2(rak::on(std::mem_fun(&Download::download), std::mem_fun(target)), std::mem_fun(setFunc)))); +} + +template +utils::Variable* +var_d2_get_value(Target target, GetFunc getFunc) { + return new utils::VariableDownloadValueSlot(rak::ftor_fn1(rak::on(rak::on(std::mem_fun(&Download::download), std::mem_fun(target)), std::mem_fun(getFunc))), NULL); +} + Download::Download(download_type d) : m_download(d), m_trackerList(d.tracker_list()), @@ -68,9 +88,8 @@ Download::Download(download_type d) : m_download.signal_chunk_failed(sigc::mem_fun(*this, &Download::receive_chunk_failed)); - m_variables.insert("connection_current", new utils::VariableStringSlot(NULL, NULL, - rak::ftor_fn1(std::mem_fun(&Download::connection_current)), - rak::ftor_fn2(std::mem_fun(&Download::set_connection_current)))); + m_variables.insert("connection_current", new utils::VariableDownloadStringSlot(rak::ftor_fn1(std::mem_fun(&Download::connection_current)), + rak::ftor_fn2(std::mem_fun(&Download::set_connection_current)))); m_variables.insert("connection_leech", new utils::VariableAny(connection_type_to_string(download_type::CONNECTION_LEECH))); m_variables.insert("connection_seed", new utils::VariableAny(connection_type_to_string(download_type::CONNECTION_SEED))); @@ -91,30 +110,26 @@ Download::Download(download_type d) : // resume/pause. m_variables.insert("state_changed", new utils::VariableObject("rtorrent", "state_changed", torrent::Object::TYPE_VALUE)); - m_variables.insert("directory", new utils::VariableStringSlot(NULL, NULL, - rak::ftor_fn1(rak::on(std::mem_fun(&Download::file_list), std::mem_fun(&torrent::FileList::root_dir))), - rak::ftor_fn2(std::mem_fun(&Download::set_root_directory)))); + m_variables.insert("directory", new utils::VariableDownloadStringSlot(rak::ftor_fn1(rak::on(std::mem_fun(&Download::file_list), std::mem_fun(&torrent::FileList::root_dir))), + rak::ftor_fn2(std::mem_fun(&Download::set_root_directory)))); + m_variables.insert("min_peers", var_d_value(&Download::download, &download_type::peers_min, &download_type::set_peers_min)); + m_variables.insert("max_peers", var_d_value(&Download::download, &download_type::peers_max, &download_type::set_peers_max)); + m_variables.insert("max_uploads", var_d_value(&Download::download, &download_type::uploads_max, &download_type::set_uploads_max)); -// m_variables.insert("info_hash", new utils::VariableStringSlot(rak::mem_fn(&m_download, &torrent::Download::info_hash), NULL)); + m_variables.insert("max_file_size", var_d_value(&Download::file_list, &file_list_type::max_file_size, &file_list_type::set_max_file_size)); - m_variables.insert("min_peers", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::peers_min), rak::mem_fn(&m_download, &download_type::set_peers_min))); - m_variables.insert("max_peers", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::peers_max), rak::mem_fn(&m_download, &download_type::set_peers_max))); - m_variables.insert("max_uploads", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::uploads_max), rak::mem_fn(&m_download, &download_type::set_uploads_max))); - - m_variables.insert("max_file_size", new utils::VariableValueSlot(rak::mem_fn(file_list(), &file_list_type::max_file_size), rak::mem_fn(file_list(), &file_list_type::set_max_file_size))); // m_variables.insert("split_file_size", new utils::VariableValueSlot(rak::mem_fn(file_list(), &file_list_type::split_file_size), rak::mem_fn(file_list(), &file_list_type::set_split_file_size))); // m_variables.insert("split_suffix", new utils::VariableStringSlot(rak::mem_fn(file_list(), &file_list_type::split_suffix), rak::mem_fn(file_list(), &file_list_type::set_split_suffix))); - m_variables.insert("up_rate", new utils::VariableValueSlot(rak::mem_fn(m_download.up_rate(), &torrent::Rate::rate), NULL)); - m_variables.insert("up_total", new utils::VariableValueSlot(rak::mem_fn(m_download.up_rate(), &torrent::Rate::total), NULL)); - m_variables.insert("down_rate", new utils::VariableValueSlot(rak::mem_fn(m_download.down_rate(), &torrent::Rate::rate), NULL)); - m_variables.insert("down_total", new utils::VariableValueSlot(rak::mem_fn(m_download.down_rate(), &torrent::Rate::total), NULL)); - m_variables.insert("skip_rate", new utils::VariableValueSlot(rak::mem_fn(m_download.skip_rate(), &torrent::Rate::rate), NULL)); - m_variables.insert("skip_total", new utils::VariableValueSlot(rak::mem_fn(m_download.skip_rate(), &torrent::Rate::total), NULL)); + m_variables.insert("up_rate", var_d2_get_value(&download_type::mutable_up_rate, &torrent::Rate::rate)); + m_variables.insert("up_total", var_d2_get_value(&download_type::mutable_up_rate, &torrent::Rate::total)); + m_variables.insert("down_rate", var_d2_get_value(&download_type::mutable_down_rate, &torrent::Rate::rate)); + m_variables.insert("down_total", var_d2_get_value(&download_type::mutable_down_rate, &torrent::Rate::total)); + m_variables.insert("skip_rate", var_d2_get_value(&download_type::mutable_skip_rate, &torrent::Rate::rate)); + m_variables.insert("skip_total", var_d2_get_value(&download_type::mutable_skip_rate, &torrent::Rate::total)); - m_variables.insert("priority", new utils::VariableValueSlot(rak::mem_fn(this, &Download::priority), rak::mem_fn(this, &Download::set_priority))); - - m_variables.insert("tracker_numwant", new utils::VariableValueSlot(rak::mem_fn(&m_trackerList, &tracker_list_type::numwant), rak::mem_fn(&m_trackerList, &tracker_list_type::set_numwant))); + m_variables.insert("priority", new utils::VariableDownloadValueSlot(rak::ftor_fn1(std::mem_fun(&Download::priority)), rak::ftor_fn2(std::mem_fun(&Download::set_priority)))); + m_variables.insert("tracker_numwant", var_d_value(&Download::tracker_list, &tracker_list_type::numwant, &tracker_list_type::set_numwant)); m_variables.insert("ignore_commands", new utils::VariableObject("rtorrent", "ignore_commands", torrent::Object::TYPE_VALUE)); } diff --git a/src/utils/variable_generic.cc b/src/utils/variable_generic.cc index 13b36f88..def7ca46 100644 --- a/src/utils/variable_generic.cc +++ b/src/utils/variable_generic.cc @@ -42,15 +42,8 @@ namespace utils { -const torrent::Object& -VariableAny::get() { - return m_variable; -} - -void -VariableAny::set(const torrent::Object& arg) { - m_variable = arg; -} +const torrent::Object& VariableAny::get() { return m_variable; } +void VariableAny::set(const torrent::Object& arg) { m_variable = arg; } void VariableValue::set(const torrent::Object& arg) { @@ -145,6 +138,11 @@ VariableObject::set_d(core::Download* download, const torrent::Object& arg) { } } +const torrent::Object& VariableDownload::get() { return m_global->get(); } +const torrent::Object& VariableDownload::get_d(core::Download* download) { return m_download->get_d(download); } +void VariableDownload::set(const torrent::Object& arg) { m_global->set(arg); } +void VariableDownload::set_d(core::Download* download, const torrent::Object& arg) { m_download->set_d(download, arg); } + // // New and prettified. // @@ -165,7 +163,7 @@ VariableVoidSlot::set(const torrent::Object& arg) { const torrent::Object& VariableValueSlot::get() { if (!m_slotGet.is_valid()) - return m_cache; + return m_cache = torrent::Object(); m_cache = m_slotGet() / m_unit; @@ -197,6 +195,40 @@ VariableValueSlot::set(const torrent::Object& arg) { } } +const torrent::Object& +VariableDownloadValueSlot::get_d(core::Download* download) { + // Should clear the cache. + if (!m_slotGetDownload.is_valid()) + return m_cache = torrent::Object(); + + return m_cache = m_slotGetDownload(download) / m_unit; +} + +void +VariableDownloadValueSlot::set_d(core::Download* download, const torrent::Object& arg) { + if (!m_slotSetDownload.is_valid()) + return; + + value_type value; + + switch (arg.type()) { + case torrent::Object::TYPE_STRING: + string_to_value_unit(arg.as_string().c_str(), &value, m_base, m_unit); + + // Check if we hit the end of the input. + + m_slotSetDownload(download, value); + break; + + case torrent::Object::TYPE_VALUE: + m_slotSetDownload(download, arg.as_value()); + break; + + default: + throw torrent::input_error("Not a value"); + } +} + const torrent::Object& VariableStringSlot::get() { if (!m_slotGet.is_valid()) @@ -225,49 +257,28 @@ VariableStringSlot::set(const torrent::Object& arg) { } const torrent::Object& -VariableStringSlot::get_d(core::Download* download) { +VariableDownloadStringSlot::get_d(core::Download* download) { // Should clear the cache. - if (!m_slotGetDownload.is_valid()) { - if (!m_slotGet.is_valid()) - return m_cache = torrent::Object(); + if (!m_slotGetDownload.is_valid()) + return m_cache = torrent::Object(); - m_cache = m_slotGet(); - - } else { - m_cache = m_slotGetDownload(download); - } - - return m_cache; + return m_cache = m_slotGetDownload(download); } void -VariableStringSlot::set_d(core::Download* download, const torrent::Object& arg) { - if (!m_slotSetDownload.is_valid()) { - if (!m_slotSet.is_valid()) - return; +VariableDownloadStringSlot::set_d(core::Download* download, const torrent::Object& arg) { + if (!m_slotSetDownload.is_valid()) + return; - switch (arg.type()) { - case torrent::Object::TYPE_STRING: - m_slotSet(arg.as_string()); - break; - case torrent::Object::TYPE_NONE: - m_slotSet(std::string()); - break; - default: - throw torrent::input_error("Not a string."); - } - - } else { - switch (arg.type()) { - case torrent::Object::TYPE_STRING: - m_slotSetDownload(download, arg.as_string()); - break; - case torrent::Object::TYPE_NONE: - m_slotSetDownload(download, std::string()); - break; - default: - throw torrent::input_error("Not a string."); - } + switch (arg.type()) { + case torrent::Object::TYPE_STRING: + m_slotSetDownload(download, arg.as_string()); + break; + case torrent::Object::TYPE_NONE: + m_slotSetDownload(download, std::string()); + break; + default: + throw torrent::input_error("Not a string."); } } diff --git a/src/utils/variable_generic.h b/src/utils/variable_generic.h index c76bec85..45d9d458 100644 --- a/src/utils/variable_generic.h +++ b/src/utils/variable_generic.h @@ -79,6 +79,22 @@ public: virtual void set(const torrent::Object& arg); }; +class VariableDownload : public Variable { +public: + VariableDownload(Variable* varGlobal, Variable* varDownload) : + m_global(varGlobal), m_download(varDownload) {} + + virtual const torrent::Object& get(); + virtual void set(const torrent::Object& arg); + + virtual const torrent::Object& get_d(core::Download* download); + virtual void set_d(core::Download* download, const torrent::Object& arg); + +protected: + Variable* m_global; + Variable* m_download; +}; + class VariableObject : public Variable { public: typedef torrent::Object::type_type Type; @@ -121,8 +137,9 @@ private: class VariableValueSlot : public Variable { public: - typedef rak::function0 slot_get_type; - typedef rak::function1 slot_set_type; + typedef rak::function0 slot_get_type; + typedef rak::function1 slot_set_type; + typedef std::pair range_type; template @@ -164,54 +181,93 @@ private: torrent::Object m_cache; }; -class VariableStringSlot : public Variable { +class VariableDownloadValueSlot : public Variable { public: - typedef rak::function0 slot_get_type; - typedef rak::function1 slot_get_d_type; - typedef rak::function1 slot_set_type; - typedef rak::function2 slot_set_d_type; + typedef rak::function1 slot_get_d_type; + typedef rak::function2 slot_set_d_type; - template - VariableStringSlot(SlotGet* slotGet, SlotSet* slotSet) { - m_slotGet.set(rak::convert_fn(slotGet)); - m_slotSet.set(rak::convert_fn(slotSet)); - m_slotGetDownload.set(NULL); - m_slotSetDownload.set(NULL); + typedef std::pair range_type; + + template + VariableDownloadValueSlot(SlotGetDownload* slotGetDownload, SlotSetDownload* slotSetDownload, + unsigned int base = 0, unsigned int unit = 1, + range_type range = range_type(std::numeric_limits::min(), std::numeric_limits::max())) : + m_base(base), + m_unit(unit), + m_range(range) { + + m_slotGetDownload.set(rak::convert_fn(slotGetDownload)); + m_slotSetDownload.set(rak::convert_fn(slotSetDownload)); } template - VariableStringSlot(void* slotGet, void* slotSet, SlotGetDownload* slotGetDownload, void* slotSetDownload) { - m_slotGet.set(NULL); - m_slotSet.set(NULL); - m_slotGetDownload.set(rak::convert_fn(slotGetDownload)); + VariableDownloadValueSlot(SlotGetDownload* slotGetDownload, void* slotSetDownload, + unsigned int base = 0, unsigned int unit = 1, + range_type range = range_type(std::numeric_limits::min(), std::numeric_limits::max())) : + m_base(base), + m_unit(unit), + m_range(range) { + + m_slotGetDownload.set(rak::convert_fn(slotGetDownload)); m_slotSetDownload.set(NULL); } - template - VariableStringSlot(void* slotGet, void* slotSet, SlotGetDownload* slotGetDownload, SlotSetDownload* slotSetDownload) { - m_slotGet.set(NULL); - m_slotSet.set(NULL); - m_slotGetDownload.set(rak::convert_fn(slotGetDownload)); - m_slotSetDownload.set(rak::convert_fn(slotSetDownload)); - } - -// template -// VariableStringSlot(SlotGet* slotGet, SlotSet* slotSet, SlotGetDownload* slotGetDownload, SlotSetDownload* slotSetDownload) { -// m_slotGet.set(slotGet != NULL ? rak::convert_fn(slotGet) : NULL); -// m_slotSet.set(slotSet != NULL ? rak::convert_fn(slotSet) : NULL); -// m_slotGetDownload.set(slotGetDownload != NULL ? rak::convert_fn(slotGetDownload) : NULL); -// m_slotSetDownload.set(slotSetDownload != NULL ? rak::convert_fn(slotSetDownload) : NULL); -// } - - virtual const torrent::Object& get(); - virtual void set(const torrent::Object& arg); - virtual const torrent::Object& get_d(core::Download* download); virtual void set_d(core::Download* download, const torrent::Object& arg); +private: + slot_get_d_type m_slotGetDownload; + slot_set_d_type m_slotSetDownload; + + unsigned int m_base; + unsigned int m_unit; + range_type m_range; + + // Store the cache here to avoid unnessesary copying and such. This + // should not result in any unresonable memory usage since few + // strings will be very large. + torrent::Object m_cache; +}; + +class VariableStringSlot : public Variable { +public: + typedef rak::function0 slot_get_type; + typedef rak::function1 slot_set_type; + + template + VariableStringSlot(SlotGet* slotGet, SlotSet* slotSet) { + m_slotGet.set(rak::convert_fn(slotGet)); + m_slotSet.set(rak::convert_fn(slotSet)); + } + + virtual const torrent::Object& get(); + virtual void set(const torrent::Object& arg); + private: slot_get_type m_slotGet; slot_set_type m_slotSet; + + // Store the cache here to avoid unnessesary copying and such. This + // should not result in any unresonable memory usage since few + // strings will be very large. + torrent::Object m_cache; +}; + +class VariableDownloadStringSlot : public Variable { +public: + typedef rak::function1 slot_get_d_type; + typedef rak::function2 slot_set_d_type; + + template + VariableDownloadStringSlot(SlotGetDownload* slotGetDownload, SlotSetDownload* slotSetDownload) { + m_slotGetDownload.set(rak::convert_fn(slotGetDownload)); + m_slotSetDownload.set(rak::convert_fn(slotSetDownload)); + } + + virtual const torrent::Object& get_d(core::Download* download); + virtual void set_d(core::Download* download, const torrent::Object& arg); + +private: slot_get_d_type m_slotGetDownload; slot_set_d_type m_slotSetDownload;