From 36251a46bfc03e121d23c15eea466efb6123b630 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 10 Jul 2007 13:14:42 +0000 Subject: [PATCH] * Allow returning torrent::Object map type's with XMLRPC. Patch by Josef Drexler. * Commands that pass through rpc::parse_command_* now support inline commands that start with a '$'. E.g 'print="$get_ip="'. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@933 e378c898-3ddf-0310-93e7-cc216c733640 --- src/rpc/command_download_slot.cc | 12 ++++---- src/rpc/command_slot.cc | 7 ----- src/rpc/parse_commands.cc | 50 ++++++++++++++------------------ src/rpc/parse_commands.h | 6 ++-- src/rpc/xmlrpc.cc | 11 +++++++ 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/rpc/command_download_slot.cc b/src/rpc/command_download_slot.cc index b796e19a..345532e0 100644 --- a/src/rpc/command_download_slot.cc +++ b/src/rpc/command_download_slot.cc @@ -106,14 +106,14 @@ CommandDownloadSlot::call_string(Command* rawCommand, core::Download* download, case torrent::Object::TYPE_STRING: return command->m_slot(download, arg); - case torrent::Object::TYPE_NONE: - throw torrent::input_error("CDS: void."); +// case torrent::Object::TYPE_NONE: +// throw torrent::input_error("CDS: void."); - case torrent::Object::TYPE_VALUE: - throw torrent::input_error("CDS: value."); +// case torrent::Object::TYPE_VALUE: +// throw torrent::input_error("CDS: value."); - case torrent::Object::TYPE_LIST: - throw torrent::input_error("CDS: list."); +// case torrent::Object::TYPE_LIST: +// throw torrent::input_error("CDS: list."); default: throw torrent::input_error("Not a string."); diff --git a/src/rpc/command_slot.cc b/src/rpc/command_slot.cc index 5a2f855c..78ba3654 100644 --- a/src/rpc/command_slot.cc +++ b/src/rpc/command_slot.cc @@ -114,11 +114,4 @@ CommandSlot::call_string(Command* rawCommand, const torrent::Object& rawArgs) { } } -// const torrent::Object& -// CommandSlot::get_generic(Command* rawCommand, const torrent::Object& args) { -// CommandVariable* variable = static_cast(rawCommand); - -// return variable->m_variable; -// } - } diff --git a/src/rpc/parse_commands.cc b/src/rpc/parse_commands.cc index d3e31621..9879dc6a 100644 --- a/src/rpc/parse_commands.cc +++ b/src/rpc/parse_commands.cc @@ -75,40 +75,17 @@ parse_command_name(const char* first, const char* last, std::string* dest) { return first; } -const char* +void parse_command_single(const char* first) { - return parse_command_single(first, first + std::strlen(first)); + parse_command_single(first, first + std::strlen(first)); } -const char* -parse_command_single(const char* first, const char* last) { - first = std::find_if(first, last, std::not1(command_map_is_space())); - - if (first == last || *first == '#') - return last; - - // Avoid using a string here? - std::string key; - first = parse_command_name(first, last, &key); - first = std::find_if(first, last, std::not1(command_map_is_space())); - - if (first == last || *first != '=') - throw torrent::input_error("Could not find '='."); - - torrent::Object args; - parse_whole_list(first + 1, last, &args); - - commands.call_command(key.c_str(), args); - - return last; -} - -const char* +torrent::Object parse_command_d_single(core::Download* download, const char* first, const char* last) { first = std::find_if(first, last, std::not1(command_map_is_space())); if (first == last || *first == '#') - return last; + return torrent::Object(); std::string key; first = parse_command_name(first, last, &key); @@ -120,9 +97,24 @@ parse_command_d_single(core::Download* download, const char* first, const char* torrent::Object args; parse_whole_list(first + 1, last, &args); - commands.call_command_d(key.c_str(), download, args); + if (args.is_list()) { + for (torrent::Object::list_type::iterator itr = args.as_list().begin(), last = args.as_list().begin(); itr != last; itr++) { + if (!itr->is_string()) + continue; - return last; + const std::string& str = itr->as_string(); + + if (*str.c_str() == '$') + *itr = parse_command_d_single(download, str.c_str() + 1, str.c_str() + str.size()); + } + + } else if (*args.as_string().c_str() == '$') { + const std::string& str = args.as_string(); + + args = parse_command_d_single(download, str.c_str() + 1, str.c_str() + str.size()); + } + + return commands.call_command_d(key.c_str(), download, args); } void diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index c277ec6e..1592013e 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -54,10 +54,10 @@ extern XmlRpc xmlrpc; const char* parse_command_name(const char* first, const char* last, std::string* dest); -const char* parse_command_single(const char* first); -const char* parse_command_single(const char* first, const char* last); +void parse_command_single(const char* first); -const char* parse_command_d_single(core::Download* download, const char* first, const char* last); +torrent::Object parse_command_d_single(core::Download* download, const char* first, const char* last); +inline torrent::Object parse_command_single(const char* first, const char* last) { return parse_command_d_single(NULL, first, last); } void parse_command_multiple(const char* first); bool parse_command_file(const std::string& path); diff --git a/src/rpc/xmlrpc.cc b/src/rpc/xmlrpc.cc index 7a48bd8e..1bb8c2e0 100644 --- a/src/rpc/xmlrpc.cc +++ b/src/rpc/xmlrpc.cc @@ -257,6 +257,17 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) { return result; } + + case torrent::Object::TYPE_MAP: + { + xmlrpc_value* result = xmlrpc_struct_new(env); + + for (torrent::Object::map_type::const_iterator itr = object.as_map().begin(), last = object.as_map().end(); itr != last; itr++) + xmlrpc_struct_set_value(env, result, itr->first.c_str(), object_to_xmlrpc(env, itr->second)); + + return result; + } + default: return xmlrpc_int_new(env, 0); }