diff --git a/src/command_events.cc b/src/command_events.cc index 79654eaa..c4248066 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -249,6 +249,38 @@ apply_download_list(const torrent::Object& rawArgs) { return result; } +torrent::Object +apply_call_download(const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + torrent::Object::list_type::const_iterator argsItr = args.begin(); + + if (argsItr == args.end() || ++argsItr == args.end()) + throw torrent::input_error("Too few arguments."); + + const torrent::Object::string_type& infoHash = args.begin()->as_string(); + + core::DownloadList* dList = control->core()->download_list(); + core::DownloadList::iterator dItr = dList->end(); + + if (infoHash.size() == 40) + dItr = dList->find_hex(infoHash.c_str()); + + if (dItr == dList->end()) + throw torrent::input_error("Not a valid info-hash."); + + torrent::Object result; + const char* command = (argsItr++)->as_string().c_str(); + + if (argsItr == args.end()) + result = rpc::call_command_d(command, *dItr, torrent::Object()); + else if (argsItr == --args.end()) + result = rpc::call_command_d(command, *dItr, *argsItr); + else + result = rpc::call_command_d_range(command, *dItr, argsItr, args.end()); + + return result; +} + void initialize_command_events() { core::DownloadList* downloadList = control->core()->download_list(); @@ -290,4 +322,5 @@ initialize_command_events() { ADD_COMMAND_VALUE_UN("close_low_diskspace", std::ptr_fun(&apply_close_low_diskspace)); ADD_COMMAND_LIST("download_list", rak::ptr_fn(&apply_download_list)); + ADD_COMMAND_LIST("call_download", rak::ptr_fn(&apply_call_download)); } diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 95b539c3..29bf5c13 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -40,7 +40,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -89,6 +92,16 @@ DownloadList::session_save() { std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadStore::save), control->core()->download_store())); } +DownloadList::iterator +DownloadList::find_hex(const char* hash) { + torrent::HashString key; + + for (torrent::HashString::iterator itr = key.begin(), last = key.end(); itr != last; itr++, hash += 2) + *itr = (rak::hexchar_to_value(*hash) << 4) + rak::hexchar_to_value(*(hash + 1)); + + return std::find_if(begin(), end(), rak::equal(key, rak::on(std::mem_fun(&Download::download), std::mem_fun(&torrent::Download::info_hash)))); +} + Download* DownloadList::create(std::istream* str, bool printLog) { torrent::Object* object = new torrent::Object; diff --git a/src/core/download_list.h b/src/core/download_list.h index 6403a772..650c884a 100644 --- a/src/core/download_list.h +++ b/src/core/download_list.h @@ -78,6 +78,8 @@ public: void session_save(); + iterator find_hex(const char* hash); + // Might move this to DownloadFactory. Download* create(std::istream* str, bool printLog); diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index e1a3dd2b..81e88ed2 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -80,7 +80,7 @@ inline int64_t call_command_value(const char* key) { return commands.ca inline void call_command_set_string(const char* key, const std::string& arg) { commands.call_command(key, torrent::Object(arg)); } inline void call_command_set_std_string(const std::string& key, const std::string& arg) { commands.call_command(key.c_str(), torrent::Object(arg)); } -inline torrent::Object call_command_d(const char* key, core::Download* download, const torrent::Object& obj) { return commands.call_command_d(key, download, obj); } +inline torrent::Object call_command_d(const char* key, core::Download* download, const torrent::Object& obj) { return commands.call_command_d(key, download, obj); } inline torrent::Object call_command_d_void(const char* key, core::Download* download) { return commands.call_command_d(key, download, torrent::Object()); } inline std::string call_command_d_string(const char* key, core::Download* download) { return commands.call_command_d(key, download, torrent::Object()).as_string(); } inline int64_t call_command_d_value(const char* key, core::Download* download) { return commands.call_command_d(key, download, torrent::Object()).as_value(); } @@ -89,6 +89,17 @@ inline void call_command_d_set_value(const char* key, core::Download* inline void call_command_d_set_string(const char* key, core::Download* download, const std::string& arg) { commands.call_command_d(key, download, torrent::Object(arg)); } inline void call_command_d_set_std_string(const std::string& key, core::Download* download, const std::string& arg) { commands.call_command_d(key.c_str(), download, torrent::Object(arg)); } +inline torrent::Object +call_command_d_range(const char* key, core::Download* download, torrent::Object::list_type::const_iterator first, torrent::Object::list_type::const_iterator last) { + torrent::Object rawArgs(torrent::Object::TYPE_LIST); + torrent::Object::list_type& args = rawArgs.as_list(); + + while (first != last) + args.push_back(*first++); + + return commands.call_command_d(key, download, rawArgs); +} + } #endif