From ac2f5a8882a1e28bd669cd2e8226f3a66c594a47 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Fri, 31 Aug 2007 11:44:21 +0000 Subject: [PATCH] * Only request from the same tracker more than once if PEX is disabled. * Added target_any. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@970 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_ui.cc | 18 ++++++++++++++++++ src/rpc/command.h | 4 ++++ src/rpc/command_map.cc | 12 ++++++++++++ src/rpc/command_map.h | 27 ++++++++++++++------------- src/rpc/parse_commands.cc | 14 ++++++++++---- src/rpc/xmlrpc.h | 11 ++++++----- 6 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/command_ui.cc b/src/command_ui.cc index 8dcf7f17..fd9af61f 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -124,6 +124,24 @@ apply_cat(const torrent::Object& rawArgs) { return result; } +// torrent::Object +// apply_if(const torrent::Object& rawArgs) { +// const torrent::Object::list_type& args = rawArgs.as_list(); + +// torrent::Object::list_type::const_iterator itr = args.begin(); + +// while (itr != args.end()) { +// if (itr->is_string() && *itr->as_string().c_str() == '$') { + +// torrent::Object tmp = rpc::parse_command( + +// } else { +// } +// } + +// return torrent::Object(); +// } + void initialize_command_ui() { ADD_VARIABLE_STRING("key_layout", "qwerty"); diff --git a/src/rpc/command.h b/src/rpc/command.h index 33379cda..d210affb 100644 --- a/src/rpc/command.h +++ b/src/rpc/command.h @@ -41,6 +41,10 @@ namespace rpc { +// Since it gets used so many places we might as well put it in the +// rpc namespace. +typedef std::pair target_type; + class Command { public: typedef torrent::Object::value_type value_type; diff --git a/src/rpc/command_map.cc b/src/rpc/command_map.cc index a601eb40..c818ebdc 100644 --- a/src/rpc/command_map.cc +++ b/src/rpc/command_map.cc @@ -60,6 +60,7 @@ CommandMap::insert(key_type key, Command* variable, int flags, const char* parm, return base_type::insert(itr, value_type(key, command_map_data_type(variable, flags, parm, doc))); } +// The functions below should be reduced to just one. void CommandMap::insert_generic(key_type key, Command* variable, generic_slot targetSlot, int flags, const char* parm, const char* doc) { iterator itr = insert(key, variable, flags, parm, doc); @@ -68,6 +69,14 @@ CommandMap::insert_generic(key_type key, Command* variable, generic_slot targetS itr->second.m_genericSlot = targetSlot; } +void +CommandMap::insert_any(key_type key, Command* variable, any_slot targetSlot, int flags, const char* parm, const char* doc) { + iterator itr = insert(key, variable, flags, parm, doc); + + itr->second.m_target = target_any; + itr->second.m_anySlot = targetSlot; +} + void CommandMap::insert_download(key_type key, Command* variable, download_slot targetSlot, int flags, const char* parm, const char* doc) { iterator itr = insert(key, variable, flags, parm, doc); @@ -122,6 +131,7 @@ CommandMap::insert(key_type key, const command_map_data_type src) { // This _should_ be optimized int just one assignment. switch (itr->second.m_target) { case target_generic: itr->second.m_genericSlot = src.m_genericSlot; break; + case target_any: itr->second.m_anySlot = src.m_anySlot; break; case target_download: itr->second.m_downloadSlot = src.m_downloadSlot; break; case target_file: itr->second.m_fileSlot = src.m_fileSlot; break; case target_peer: itr->second.m_peerSlot = src.m_peerSlot; break; @@ -144,6 +154,7 @@ CommandMap::call_command(key_type key, const mapped_type& arg, target_type targe // This _should_ be optimized int just two calls. switch (itr->second.m_target) { case target_generic: return itr->second.m_genericSlot (itr->second.m_variable, arg); + case target_any: return itr->second.m_anySlot (itr->second.m_variable, target, arg); case target_download: return itr->second.m_downloadSlot(itr->second.m_variable, (core::Download*)target.second, arg); case target_peer: return itr->second.m_peerSlot (itr->second.m_variable, (torrent::Peer*)target.second, arg); case target_tracker: return itr->second.m_trackerSlot (itr->second.m_variable, (torrent::Tracker*)target.second, arg); @@ -162,6 +173,7 @@ CommandMap::call_command(const_iterator itr, const mapped_type& arg, target_type // This _should_ be optimized int just two calls. switch (itr->second.m_target) { case target_generic: return itr->second.m_genericSlot (itr->second.m_variable, arg); + case target_any: return itr->second.m_anySlot (itr->second.m_variable, target, arg); case target_download: return itr->second.m_downloadSlot(itr->second.m_variable, (core::Download*)target.second, arg); case target_peer: return itr->second.m_peerSlot (itr->second.m_variable, (torrent::Peer*)target.second, arg); case target_tracker: return itr->second.m_trackerSlot (itr->second.m_variable, (torrent::Tracker*)target.second, arg); diff --git a/src/rpc/command_map.h b/src/rpc/command_map.h index 3e1e189c..ef6a33c8 100644 --- a/src/rpc/command_map.h +++ b/src/rpc/command_map.h @@ -42,6 +42,8 @@ #include #include +#include "command.h" + namespace core { class Download; } @@ -55,8 +57,6 @@ namespace torrent { namespace rpc { -class Command; - struct command_map_comp : public std::binary_function { bool operator () (const char* arg1, const char* arg2) const { return std::strcmp(arg1, arg2) < 0; } }; @@ -65,7 +65,10 @@ struct command_map_data_type { // Some commands will need to share data, like get/set a variable. So // instead of using a single virtual member function, each command // will register a member function pointer to be used instead. + // + // The any_slot should perhaps replace generic_slot? typedef const torrent::Object (*generic_slot) (Command*, const torrent::Object&); + typedef const torrent::Object (*any_slot) (Command*, target_type, const torrent::Object&); typedef const torrent::Object (*download_slot) (Command*, core::Download*, const torrent::Object&); typedef const torrent::Object (*file_slot) (Command*, torrent::File*, const torrent::Object&); typedef const torrent::Object (*file_itr_slot) (Command*, torrent::FileListIterator*, const torrent::Object&); @@ -81,6 +84,7 @@ struct command_map_data_type { union { generic_slot m_genericSlot; + any_slot m_anySlot; download_slot m_downloadSlot; file_slot m_fileSlot; file_itr_slot m_fileItrSlot; @@ -100,6 +104,7 @@ public: typedef std::map base_type; typedef command_map_data_type::generic_slot generic_slot; + typedef command_map_data_type::any_slot any_slot; typedef command_map_data_type::download_slot download_slot; typedef command_map_data_type::file_slot file_slot; typedef command_map_data_type::file_itr_slot file_itr_slot; @@ -118,14 +123,13 @@ public: using base_type::end; using base_type::find; - typedef std::pair target_type; - static const int target_generic = 0; - static const int target_download = 1; - static const int target_peer = 2; - static const int target_tracker = 3; - static const int target_file = 4; - static const int target_file_itr = 5; + static const int target_any = 1; + static const int target_download = 2; + static const int target_peer = 3; + static const int target_tracker = 4; + static const int target_file = 5; + static const int target_file_itr = 6; static const int flag_dont_delete = 0x1; static const int flag_public_xmlrpc = 0x2; @@ -139,6 +143,7 @@ public: iterator insert(key_type key, Command* variable, int flags, const char* parm, const char* doc); void insert_generic (key_type key, Command* variable, generic_slot targetSlot, int flags, const char* parm, const char* doc); + void insert_any (key_type key, Command* variable, any_slot targetSlot, int flags, const char* parm, const char* doc); void insert_download(key_type key, Command* variable, download_slot targetSlot, int flags, const char* parm, const char* doc); void insert_peer (key_type key, Command* variable, peer_slot targetSlot, int flags, const char* parm, const char* doc); void insert_tracker (key_type key, Command* variable, tracker_slot targetSlot, int flags, const char* parm, const char* doc); @@ -160,10 +165,6 @@ private: void operator = (const CommandMap&); }; -// Since it gets used so many places we might as well put it in the -// rpc namespace. -typedef CommandMap::target_type target_type; - inline target_type make_target() { return target_type((int)CommandMap::target_generic, NULL); } inline target_type make_target(core::Download* target) { return target_type((int)CommandMap::target_download, target); } inline target_type make_target(torrent::Peer* target) { return target_type((int)CommandMap::target_peer, target); } diff --git a/src/rpc/parse_commands.cc b/src/rpc/parse_commands.cc index 7757ed1f..2d6de082 100644 --- a/src/rpc/parse_commands.cc +++ b/src/rpc/parse_commands.cc @@ -82,10 +82,16 @@ parse_count_escaped(const char* first, const char* last) { // // Find a better name. void -parse_command_execute(CommandMap::target_type target, torrent::Object* object) { +parse_command_execute(target_type target, torrent::Object* object) { if (object->is_list()) { - for (torrent::Object::list_type::iterator itr = object->as_list().begin(), last = object->as_list().end(); itr != last; itr++) + // For now, until we can flag the lists we want executed and those + // we can't, disable recursion completely. + for (torrent::Object::list_type::iterator itr = object->as_list().begin(), last = object->as_list().end(); itr != last; itr++) { + if (itr->is_list()) + continue; + parse_command_execute(target, &*itr); + } } else if (*object->as_string().c_str() == '$') { const std::string& str = object->as_string(); @@ -97,7 +103,7 @@ parse_command_execute(CommandMap::target_type target, torrent::Object* object) { // Set 'download' to NULL to call the generic functions, thus reusing // the code below for both cases. parse_command_type -parse_command(CommandMap::target_type target, const char* first, const char* last) { +parse_command(target_type target, const char* first, const char* last) { first = std::find_if(first, last, std::not1(command_map_is_space())); if (first == last || *first == '#') @@ -133,7 +139,7 @@ parse_command(CommandMap::target_type target, const char* first, const char* las } void -parse_command_multiple(CommandMap::target_type target, const char* first, const char* last) { +parse_command_multiple(target_type target, const char* first, const char* last) { while (first != last) { // Should we check the return value? Probably not necessary as // parse_args throws on unquoted multi-word input. diff --git a/src/rpc/xmlrpc.h b/src/rpc/xmlrpc.h index 8988d10c..3c6dfd72 100644 --- a/src/rpc/xmlrpc.h +++ b/src/rpc/xmlrpc.h @@ -64,11 +64,12 @@ public: // These need to match CommandMap type values. static const int call_generic = 0; - static const int call_download = 1; - static const int call_peer = 2; - static const int call_tracker = 3; - static const int call_file = 4; - static const int call_file_itr = 5; + static const int call_any = 1; + static const int call_download = 2; + static const int call_peer = 3; + static const int call_tracker = 4; + static const int call_file = 5; + static const int call_file_itr = 6; XmlRpc() : m_env(NULL), m_registry(NULL), m_dialect(dialect_i8) {}