From b530d35d9477c5dbaa8a00792bf6656b69a6bfa9 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 28 Apr 2010 15:19:18 +0000 Subject: [PATCH] * More work on rpc::object_storage and moving simple functions over to it. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1165 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_download.cc | 1 - src/command_dynamic.cc | 236 +++++++++++++++++++++---------- src/command_events.cc | 1 - src/command_helpers.cc | 2 - src/command_helpers.h | 36 +++-- src/command_local.cc | 3 +- src/command_network.cc | 1 - src/command_scheduler.cc | 1 - src/command_ui.cc | 1 - src/control.cc | 3 + src/control.h | 3 + src/main.cc | 68 +++++---- src/rpc/Makefile.am | 4 - src/rpc/command_new_slot.h | 5 + src/rpc/command_variable.cc | 169 ---------------------- src/rpc/command_variable.h | 94 ------------ src/rpc/object_storage.cc | 80 +++++++++-- src/rpc/object_storage.h | 51 +++++-- test/Makefile.am | 2 + test/rpc/object_storage_test.cc | 30 ++-- test/src/command_dynamic_test.cc | 60 ++++++++ test/src/command_dynamic_test.h | 20 +++ 22 files changed, 450 insertions(+), 421 deletions(-) delete mode 100644 src/rpc/command_variable.cc delete mode 100644 src/rpc/command_variable.h create mode 100644 test/src/command_dynamic_test.cc create mode 100644 test/src/command_dynamic_test.h diff --git a/src/command_download.cc b/src/command_download.cc index 745c6f15..00667cb7 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -56,7 +56,6 @@ #include "core/download.h" #include "core/download_store.h" #include "core/manager.h" -#include "rpc/command_variable.h" #include "globals.h" #include "control.h" diff --git a/src/command_dynamic.cc b/src/command_dynamic.cc index 8a2b9d9a..be1586c6 100644 --- a/src/command_dynamic.cc +++ b/src/command_dynamic.cc @@ -41,7 +41,7 @@ #include "globals.h" #include "control.h" #include "command_helpers.h" -#include "rpc/command_variable.h" +#include "rpc/parse.h" std::string system_method_generate_command(torrent::Object::list_const_iterator first, torrent::Object::list_const_iterator last) { @@ -66,6 +66,106 @@ create_new_key(const std::string& key, const char postfix[postfix_size]) { return buffer; } +// torrent::Object +// system_method_insert_function(const torrent::Object::list_type& args, int flags) { + +// } + +torrent::Object +system_method_insert_object(const torrent::Object::list_type& args, int flags) { + if (args.empty()) + throw torrent::input_error("Invalid argument count."); + + torrent::Object::list_const_iterator itrArgs = args.begin(); + const std::string& rawKey = (itrArgs++)->as_string(); + + if (rawKey.empty() || + control->object_storage()->find_local(torrent::raw_string::from_string(rawKey)) != control->object_storage()->end(0) || + rpc::commands.has(rawKey) || rpc::commands.has(rawKey + ".set")) + throw torrent::input_error("Invalid key."); + + torrent::Object value; + + switch (flags & rpc::object_storage::mask_type) { + case rpc::object_storage::flag_bool_type: + case rpc::object_storage::flag_value_type: + value = itrArgs != args.end() ? rpc::convert_to_value(*itrArgs) : int64_t(); + break; + case rpc::object_storage::flag_string_type: + value = itrArgs != args.end() ? rpc::convert_to_string(*itrArgs) : ""; + break; + case rpc::object_storage::flag_function_type: + value = itrArgs != args.end() ? system_method_generate_command(itrArgs, args.end()) : ""; + break; + default: + throw torrent::input_error("Invalid type."); + } + + int cmd_flags = 0; + + if (!(flags & rpc::object_storage::flag_static)) + cmd_flags |= rpc::CommandMap::flag_modifiable; + if (!(flags & rpc::object_storage::flag_private)) + cmd_flags |= rpc::CommandMap::flag_public_xmlrpc; + + rpc::object_storage::iterator obj_itr = control->object_storage()->insert_str(rawKey, value, flags); + + // Add commands: + rpc::command_base* command_get = new rpc::command_base(); + + if ((flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_function_type) + command_get->set_function_2 > + (std::tr1::bind(&rpc::object_storage::call_function_str, control->object_storage(), + rawKey, std::tr1::placeholders::_1, std::tr1::placeholders::_2)); + else + command_get->set_function_2 > + (std::tr1::bind(&rpc::object_storage::get_str, control->object_storage(), rawKey)); + + rpc::commands.insert_type(create_new_key<0>(rawKey, ""), + command_get, + &rpc::command_base_call, + cmd_flags, NULL, NULL); + + // TODO: Next... Make test class for this. + +// // Ehm... no proper handling if these throw. + + if (!(flags & rpc::object_storage::flag_constant)) { + rpc::command_base* command_set = new rpc::command_base(); + rpc::command_base_call_type command_call = NULL; + + switch (flags & rpc::object_storage::mask_type) { + case rpc::object_storage::flag_bool_type: + command_set->set_function_2 > + (std::tr1::bind(&rpc::object_storage::set_str_bool, control->object_storage(), rawKey, std::tr1::placeholders::_2)); + + command_call = &rpc::command_base_call_value; + break; + case rpc::object_storage::flag_value_type: + command_set->set_function_2 > + (std::tr1::bind(&rpc::object_storage::set_str_value, control->object_storage(), rawKey, std::tr1::placeholders::_2)); + + command_call = &rpc::command_base_call_value; + break; + case rpc::object_storage::flag_string_type: + command_set->set_function_2 > + (std::tr1::bind(&rpc::object_storage::set_str_string, control->object_storage(), rawKey, std::tr1::placeholders::_2)); + + command_call = &rpc::command_base_call_string; + break; + case rpc::object_storage::flag_function_type: + default: + delete command_set; + return torrent::Object(); + } + + rpc::commands.insert_type(create_new_key<5>(rawKey, ".set"), + command_set, command_call, cmd_flags, NULL, NULL); + } + + return torrent::Object(); +} + // method.insert {name, "simple|private|const", ...} // method.insert {name, "multi|private|const"} // method.insert {name, "value|private|const"} @@ -109,62 +209,53 @@ system_method_insert(const torrent::Object::list_type& args) { rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, slot, flags, NULL, NULL); } else if (options.find("simple") != std::string::npos) { - rpc::command_base* command = new rpc::command_base(); + torrent::Object::list_type new_args; + new_args.push_back(rawKey); + new_args.push_back(system_method_generate_command(++itrArgs, args.end())); - command->set_function >::type>(std::tr1::bind(&rpc::command_function_call_str, - system_method_generate_command(++itrArgs, args.end()), - std::tr1::placeholders::_1, - std::tr1::placeholders::_2)); + int new_flags = rpc::object_storage::flag_function_type; - rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, &rpc::command_base_call, - flags, NULL, NULL); + if (options.find("static") != std::string::npos) + new_flags |= rpc::object_storage::flag_static; + if (options.find("private") != std::string::npos) + new_flags |= rpc::object_storage::flag_private; + if (options.find("const") != std::string::npos) + new_flags |= rpc::object_storage::flag_constant; -// rpc::Command::any_slot slot = &rpc::CommandFunction::call; -// rpc::Command* command = new rpc::CommandFunction(system_method_generate_command(++itrArgs, args.end())); - -// rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, slot, flags, NULL, NULL); + return system_method_insert_object(new_args, new_flags); } else if (options.find("value") != std::string::npos || options.find("bool") != std::string::npos || options.find("string") != std::string::npos || - options.find("list") != std::string::npos) { - rpc::CommandVariable *command; - rpc::Command::any_slot getSlot; - rpc::Command::any_slot setSlot; - - if (options.find("value") != std::string::npos) { - command = new rpc::CommandVariable(int64_t()); - getSlot = &rpc::CommandVariable::get_value; - setSlot = &rpc::CommandVariable::set_value; - } else if (options.find("bool") != std::string::npos) { - command = new rpc::CommandVariable(int64_t()); - getSlot = &rpc::CommandVariable::get_bool; - setSlot = &rpc::CommandVariable::set_bool; - } else if (options.find("string") != std::string::npos) { - command = new rpc::CommandVariable(std::string()); - getSlot = &rpc::CommandVariable::get_string; - setSlot = &rpc::CommandVariable::set_string; - } else { -// command = new rpc::CommandVariable(torrent::Object::create_list()); -// getSlot = &rpc::CommandVariable::get_string; -// setSlot = &rpc::CommandVariable::set_string; - throw torrent::input_error("No support for 'list' variable type."); - } - - // Only allow deletion after adding a flag that ensures we search - // the command map for duplicates of 'command', and delete them - // all at the same time. - flags &= ~rpc::CommandMap::flag_modifiable; - - rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, getSlot, flags, NULL, NULL); - - if (options.find("static") == std::string::npos) - rpc::commands.insert_type(create_new_key<5>(rawKey, ".set"), command, setSlot, flags | rpc::CommandMap::flag_dont_delete, NULL, NULL); + options.find("list") != std::string::npos || + options.find("simple") != std::string::npos) { + torrent::Object::list_type new_args; + new_args.push_back(rawKey); if (++itrArgs != args.end()) - (*setSlot)(command, rpc::make_target(), *itrArgs); + new_args.insert(new_args.end(), itrArgs, args.end()); + + int new_flags; + + if (options.find("value") != std::string::npos) + new_flags = rpc::object_storage::flag_value_type; + else if (options.find("bool") != std::string::npos) + new_flags = rpc::object_storage::flag_bool_type; + else if (options.find("string") != std::string::npos) + new_flags = rpc::object_storage::flag_string_type; + else if (options.find("simple") != std::string::npos) + new_flags = rpc::object_storage::flag_function_type; + else + throw torrent::input_error("No support for 'list' variable type."); + + if (options.find("static") != std::string::npos) + new_flags |= rpc::object_storage::flag_static; + if (options.find("private") != std::string::npos) + new_flags |= rpc::object_storage::flag_private; + if (options.find("const") != std::string::npos) + new_flags |= rpc::object_storage::flag_constant; + + return system_method_insert_object(new_args, new_flags); } else { // THROW. @@ -208,32 +299,18 @@ system_method_redirect(const torrent::Object::list_type& args) { } torrent::Object -system_method_get(const torrent::Object::string_type& args) { -// rpc::CommandFunction* function; -// rpc::CommandMap::iterator itr = rpc::commands.find(args.c_str()); +system_method_set_function(const torrent::Object::list_type& args) { + if (args.empty()) + throw torrent::input_error("Invalid argument count."); -// if (itr == rpc::commands.end() || -// (function = dynamic_cast(itr->second.m_variable)) == NULL) -// throw torrent::input_error("Command not modifiable or wrong type."); + rpc::object_storage::local_iterator itr = + control->object_storage()->find_local(torrent::raw_string::from_string(args.front().as_string())); -// return torrent::Object(function->command()); - return torrent::Object(); -} + if (itr == control->object_storage()->end(0) || itr->second.flags & rpc::object_storage::flag_constant) + throw torrent::input_error("Command is not modifiable."); -torrent::Object -system_method_set(const torrent::Object::list_type& args) { -// if (args.empty()) -// throw torrent::input_error("Invalid argument count."); - -// rpc::CommandFunction* function; -// rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str()); - -// if (itr == rpc::commands.end() || !rpc::commands.is_modifiable(itr) || -// (function = dynamic_cast(itr->second.m_variable)) == NULL) -// throw torrent::input_error("Command not modifiable or wrong type."); - -// function->set_command(system_method_generate_command(++args.begin(), args.end())); - return torrent::Object(); + return control->object_storage()->set_str_function(args.front().as_string(), + system_method_generate_command(++args.begin(), args.end())); } torrent::Object @@ -292,13 +369,26 @@ system_method_list_keys(const torrent::Object::string_type& args) { return rawResult; } +#define CMD2_METHOD_INSERT(key, flags) \ + CMD2_ANY_LIST(key, std::tr1::bind(&system_method_insert_object, std::tr1::placeholders::_2, flags)); + void initialize_command_dynamic() { CMD2_ANY_LIST ("method.insert", std::tr1::bind(&system_method_insert, std::tr1::placeholders::_2)); + + CMD2_ANY_LIST ("method.insert.value", std::tr1::bind(&system_method_insert_object, std::tr1::placeholders::_2, + rpc::object_storage::flag_value_type)); + + CMD2_METHOD_INSERT("method.insert.simple", rpc::object_storage::flag_function_type); + CMD2_METHOD_INSERT("method.insert.c_simple", rpc::object_storage::flag_constant | rpc::object_storage::flag_function_type); + CMD2_METHOD_INSERT("method.insert.s_c_simple", rpc::object_storage::flag_static | + rpc::object_storage::flag_constant |rpc::object_storage::flag_function_type); + CMD2_ANY_STRING ("method.erase", std::tr1::bind(&system_method_erase, std::tr1::placeholders::_2)); CMD2_ANY_LIST ("method.redirect", std::tr1::bind(&system_method_redirect, std::tr1::placeholders::_2)); - CMD2_ANY_STRING ("method.get", std::tr1::bind(&system_method_get, std::tr1::placeholders::_2)); - CMD2_ANY_LIST ("method.set", std::tr1::bind(&system_method_set, std::tr1::placeholders::_2)); + CMD2_ANY_STRING ("method.get", std::tr1::bind(&rpc::object_storage::get_str, control->object_storage(), + std::tr1::placeholders::_2)); + CMD2_ANY_LIST ("method.set", std::tr1::bind(&system_method_set_function, std::tr1::placeholders::_2)); CMD2_ANY_LIST ("method.set_key", std::tr1::bind(&system_method_set_key, std::tr1::placeholders::_2)); CMD2_ANY_LIST ("method.has_key", std::tr1::bind(&system_method_has_key, std::tr1::placeholders::_2)); CMD2_ANY_STRING ("method.list_keys", std::tr1::bind(&system_method_list_keys, std::tr1::placeholders::_2)); diff --git a/src/command_events.cc b/src/command_events.cc index 38f420ff..0c8bdc5a 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -50,7 +50,6 @@ #include "core/manager.h" #include "core/view_manager.h" #include "rpc/command_scheduler.h" -#include "rpc/command_variable.h" #include "rpc/parse.h" #include "rpc/parse_commands.h" diff --git a/src/command_helpers.cc b/src/command_helpers.cc index 686b0b8a..2783ac73 100644 --- a/src/command_helpers.cc +++ b/src/command_helpers.cc @@ -38,8 +38,6 @@ #include -#include "rpc/command_variable.h" - #include "globals.h" #include "control.h" #include "command_helpers.h" diff --git a/src/command_helpers.h b/src/command_helpers.h index 84a79a15..5a49df94 100644 --- a/src/command_helpers.h +++ b/src/command_helpers.h @@ -40,9 +40,9 @@ #include "rpc/command_new_slot.h" #include "rpc/command_function.h" #include "rpc/parse_commands.h" +#include "rpc/object_storage.h" namespace rpc { - class CommandVariable; class CommandObjectPtr; } @@ -61,15 +61,15 @@ void initialize_commands(); // New std::function based command_base helper functions: // -#define CMD2_A_FUNCTION(key, function, slot, parm, doc) \ +#define CMD2_A_FUNCTION(key, function, slot, parm, doc) \ commandNewSlotItr->set_function::type>(slot); \ rpc::commands.insert_type(key, commandNewSlotItr++, &rpc::function, \ - rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, NULL, NULL); + rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, NULL, NULL); -#define CMD2_A_FUNCTION_PRIVATE(key, function, slot, parm, doc) \ +#define CMD2_A_FUNCTION_PRIVATE(key, function, slot, parm, doc) \ commandNewSlotItr->set_function::type>(slot); \ rpc::commands.insert_type(key, commandNewSlotItr++, &rpc::function, \ - rpc::CommandMap::flag_dont_delete, NULL, NULL); + rpc::CommandMap::flag_dont_delete, NULL, NULL); #define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call, slot, "i:", "") @@ -112,13 +112,31 @@ void initialize_commands(); #define CMD2_TRACKER_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value, object_convert_void(slot), "i:i", "") #define CMD2_VAR_BOOL(key, value) \ - rpc::commands.call("method.insert", rpc::create_object_list(key, "bool|const", int64_t(value))); + control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_bool_type); \ + CMD2_ANY(key, std::tr1::bind(&rpc::object_storage::get, control->object_storage(), \ + torrent::raw_string::from_c_str(key))); \ + CMD2_ANY_VALUE(key ".set", std::tr1::bind(&rpc::object_storage::set_bool, control->object_storage(), \ + torrent::raw_string::from_c_str(key), std::tr1::placeholders::_2)); + #define CMD2_VAR_VALUE(key, value) \ - rpc::commands.call("method.insert", rpc::create_object_list(key, "value|const", int64_t(value))); + control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_value_type); \ + CMD2_ANY(key, std::tr1::bind(&rpc::object_storage::get, control->object_storage(), \ + torrent::raw_string::from_c_str(key))); \ + CMD2_ANY_VALUE(key ".set", std::tr1::bind(&rpc::object_storage::set_value, control->object_storage(), \ + torrent::raw_string::from_c_str(key), std::tr1::placeholders::_2)); + #define CMD2_VAR_STRING(key, value) \ - rpc::commands.call("method.insert", rpc::create_object_list(key, "string|const", std::string(value))); + control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \ + CMD2_ANY(key, std::tr1::bind(&rpc::object_storage::get, control->object_storage(), \ + torrent::raw_string::from_c_str(key))); \ + CMD2_ANY_STRING(key ".set", std::tr1::bind(&rpc::object_storage::set_string, control->object_storage(), \ + torrent::raw_string::from_c_str(key), std::tr1::placeholders::_2)); + + #define CMD2_VAR_C_STRING(key, value) \ - rpc::commands.call("method.insert", rpc::create_object_list(key, "string|static|const", std::string(value))); + control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \ + CMD2_ANY(key, std::tr1::bind(&rpc::object_storage::get, control->object_storage(), \ + torrent::raw_string::from_c_str(key))); #define CMD2_FUNC_SINGLE(key, cmds) \ CMD2_ANY(key, std::tr1::bind(&rpc::command_function_call, torrent::raw_string::from_c_str(cmds), \ diff --git a/src/command_local.cc b/src/command_local.cc index c073095e..3b656e16 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -50,7 +50,6 @@ #include "core/download_store.h" #include "core/manager.h" #include "rak/string_manip.h" -#include "rpc/command_variable.h" #include "rpc/parse_commands.h" #include "rpc/scgi.h" #include "utils/file_status_cache.h" @@ -180,7 +179,7 @@ initialize_command_local() { CMD2_VAR_C_STRING("system.client_version", PACKAGE_VERSION); CMD2_VAR_C_STRING("system.library_version", torrent::version()); - CMD2_VAR_VALUE ("system.file.allocate", (int64_t)0); + CMD2_VAR_VALUE ("system.file.allocate", 0); CMD2_VAR_VALUE ("system.file.max_size", -1); CMD2_VAR_VALUE ("system.file.split_size", -1); CMD2_VAR_STRING ("system.file.split_suffix", ".part"); diff --git a/src/command_network.cc b/src/command_network.cc index 69d7bc68..a5d39ad0 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -54,7 +54,6 @@ #include "core/manager.h" #include "rpc/scgi.h" #include "ui/root.h" -#include "rpc/command_variable.h" #include "rpc/parse.h" #include "rpc/parse_commands.h" diff --git a/src/command_scheduler.cc b/src/command_scheduler.cc index 850f147f..887d10f7 100644 --- a/src/command_scheduler.cc +++ b/src/command_scheduler.cc @@ -43,7 +43,6 @@ #include "core/download_list.h" #include "core/view.h" #include "core/view_manager.h" -#include "rpc/command_variable.h" #include "globals.h" #include "control.h" diff --git a/src/command_ui.cc b/src/command_ui.cc index 84b9f9fa..cca329a7 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -47,7 +47,6 @@ #include "core/view_manager.h" #include "ui/root.h" #include "ui/download_list.h" -#include "rpc/command_variable.h" #include "rpc/parse.h" #include "globals.h" diff --git a/src/control.cc b/src/control.cc index f674a725..dd535eaf 100644 --- a/src/control.cc +++ b/src/control.cc @@ -53,6 +53,7 @@ #include "rpc/command_scheduler.h" #include "rpc/parse_commands.h" #include "rpc/scgi.h" +#include "rpc/object_storage.h" #include "ui/root.h" #include "control.h" @@ -64,6 +65,7 @@ Control::Control() : m_inputStdin(new input::InputEvent(STDIN_FILENO)), m_commandScheduler(new rpc::CommandScheduler()), + m_objectStorage(new rpc::object_storage()), m_tick(0), m_shutdownReceived(false), @@ -85,6 +87,7 @@ Control::~Control() { delete m_input; delete m_commandScheduler; + delete m_objectStorage; delete m_viewManager; diff --git a/src/control.h b/src/control.h index 47406912..3dc65ec2 100644 --- a/src/control.h +++ b/src/control.h @@ -65,6 +65,7 @@ namespace input { namespace rpc { class CommandScheduler; class XmlRpc; + class object_storage; } class Control { @@ -96,6 +97,7 @@ public: input::InputEvent* input_stdin() { return m_inputStdin; } rpc::CommandScheduler* command_scheduler() { return m_commandScheduler; } + rpc::object_storage* object_storage() { return m_objectStorage; } uint64_t tick() const { return m_tick; } void inc_tick() { m_tick++; } @@ -117,6 +119,7 @@ private: input::InputEvent* m_inputStdin; rpc::CommandScheduler* m_commandScheduler; + rpc::object_storage* m_objectStorage; uint64_t m_tick; diff --git a/src/main.cc b/src/main.cc index 1a93b212..649eef04 100644 --- a/src/main.cc +++ b/src/main.cc @@ -221,15 +221,6 @@ main(int argc, char** argv) { "method.set_key = event.download.erased, !_download_list, ui.unfocus_download=\n" "method.set_key = event.download.erased, ~_delete_tied, d.delete_tied=\n" - "method.insert = ratio.enable, simple|const,group.seeding.ratio.enable=\n" - "method.insert = ratio.disable,simple|const,group.seeding.ratio.disable=\n" - "method.insert = ratio.min, simple|const,group.seeding.ratio.min=\n" - "method.insert = ratio.max, simple|const,group.seeding.ratio.max=\n" - "method.insert = ratio.upload, simple|const,group.seeding.ratio.upload=\n" - "method.insert = ratio.min.set, simple|const,group.seeding.ratio.min.set=$argument.0=\n" - "method.insert = ratio.max.set, simple|const,group.seeding.ratio.max.set=$argument.0=\n" - "method.insert = ratio.upload.set,simple|const,group.seeding.ratio.upload.set=$argument.0=\n" - "method.insert = group.insert_persistent_view,simple|const," "view.add=$argument.0=,view.persistent=$argument.0=,\"group.insert=$argument.0=,$argument.0=\"\n" @@ -303,24 +294,19 @@ main(int argc, char** argv) { "encryption=allow_incoming,prefer_plaintext,enable_retry\n" ); + CMD2_REDIRECT ("ratio.enable", "group.seeding.ratio.enable"); + CMD2_REDIRECT ("ratio.disable", "group.seeding.ratio.disable"); + CMD2_REDIRECT ("ratio.min", "group.seeding.ratio.min"); + CMD2_REDIRECT ("ratio.max", "group.seeding.ratio.max"); + CMD2_REDIRECT ("ratio.upload", "group.seeding.ratio.upload"); + CMD2_REDIRECT ("ratio.min.set", "group.seeding.ratio.min.set"); + CMD2_REDIRECT ("ratio.max.set", "group.seeding.ratio.max.set"); + CMD2_REDIRECT ("ratio.upload.set", "group.seeding.ratio.upload.set"); + // Deprecated commands. Don't use these anymore. if (!OptionParser::has_flag('D', argc, argv)) { // Deprecated in 0.7.0: - // - // List of cleaned up files: - // * command_download.cc - // * command_dynamic.cc - // * command_events.cc - // * command_file.cc - // * command_helpers.cc - // + command_local.cc - // * command_network.cc - // * command_object.cc - // * command_peer.cc - // * command_scheduler.cc - // * command_tracker.cc - // * command_ui.cc CMD2_REDIRECT_GENERIC("system.method.insert", "method.insert"); CMD2_REDIRECT_GENERIC("system.method.erase", "method.erase"); @@ -413,7 +399,33 @@ main(int argc, char** argv) { CMD2_REDIRECT_GENERIC("set_scgi_dont_route", "network.scgi.dont_route.set"); CMD2_REDIRECT ("get_scgi_dont_route", "network.scgi.dont_route"); - CMD2_REDIRECT ("xmlrpc_dialect", "network.xmlrpc.size_limit.set"); + // + // XMLRPC stuff: + // + + CMD2_REDIRECT_GENERIC("xmlrpc_dialect", "network.xmlrpc.dialect.set"); + CMD2_REDIRECT_GENERIC("set_xmlrpc_dialect", "network.xmlrpc.dialect.set"); + + CMD2_REDIRECT_GENERIC("xmlrpc_size_limit", "network.xmlrpc.size_limit.set"); + CMD2_REDIRECT ("get_xmlrpc_size_limit", "network.xmlrpc.size_limit"); + CMD2_REDIRECT_GENERIC("set_xmlrpc_size_limit", "network.xmlrpc.size_limit.set"); + + // + // HTTP stuff: + // + + CMD2_REDIRECT_GENERIC("http_capath", "network.http.capath.set"); + CMD2_REDIRECT ("get_http_capath", "network.http.capath"); + CMD2_REDIRECT_GENERIC("set_http_capath", "network.http.capath.set"); + + CMD2_REDIRECT_GENERIC("http_cacert", "network.http.cacert.set"); + CMD2_REDIRECT ("get_http_cacert", "network.http.cacert"); + CMD2_REDIRECT_GENERIC("set_http_cacert", "network.http.cacert.set"); + + CMD2_REDIRECT_GENERIC("http_proxy_address", "network.http.proxy_address.set"); + CMD2_REDIRECT ("get_http_proxy_address", "network.http.proxy_address"); + CMD2_REDIRECT_GENERIC("set_http_proxy_address", "network.http.proxy_address.set"); + CMD2_REDIRECT ("get_connection_leech", "connection_leech"); CMD2_REDIRECT_GENERIC("set_connection_leech", "connection_leech.set"); @@ -424,6 +436,10 @@ main(int argc, char** argv) { CMD2_REDIRECT ("get_peer_exchange", "protocol.pex"); CMD2_REDIRECT_GENERIC("set_peer_exchange", "protocol.pex.set"); + // + // DHT stuff + // + CMD2_REDIRECT ("dht", "dht.mode.set"); CMD2_REDIRECT ("dht_add_node", "dht.add_node"); CMD2_REDIRECT ("dht_statistics", "dht.statistics"); @@ -442,6 +458,10 @@ main(int argc, char** argv) { CMD2_REDIRECT_GENERIC("set_session_on_completion", "system.session.on_completion.set"); CMD2_REDIRECT ("check_hash", "pieces.hash.on_completion.set"); + CMD2_REDIRECT ("get_check_hash", "pieces.hash.on_completion"); + CMD2_REDIRECT_GENERIC("set_check_hash", "pieces.hash.on_completion.set"); + + // CMD2_REDIRECT ("get_hash_interval", "pieces.hash.interval"); // // Download: diff --git a/src/rpc/Makefile.am b/src/rpc/Makefile.am index bbbeb116..1ee2903b 100644 --- a/src/rpc/Makefile.am +++ b/src/rpc/Makefile.am @@ -13,10 +13,6 @@ libsub_rpc_a_SOURCES = \ command_scheduler_item.h \ command_new_slot.cc \ command_new_slot.h \ - command_variable.cc \ - command_variable.h \ - command_new_slot.cc \ - command_new_slot.h \ exec_file.cc \ exec_file.h \ object_storage.cc \ diff --git a/src/rpc/command_new_slot.h b/src/rpc/command_new_slot.h index dfabc99f..dad293bf 100644 --- a/src/rpc/command_new_slot.h +++ b/src/rpc/command_new_slot.h @@ -69,6 +69,11 @@ public: template void set_function(T s, int value = command_base_is_valid::value) { _pod() = s; } + template + void set_function_2(typename command_base_is_type::type s, int value = command_base_is_valid::type>::value) { + _pod::type>() = s; + } + // The std::function object in GCC is castable between types with a // pointer to a struct of ctor/dtor/calls for non-POD slots. As such // it should be safe to cast between different std::function diff --git a/src/rpc/command_variable.cc b/src/rpc/command_variable.cc deleted file mode 100644 index 24e73bd1..00000000 --- a/src/rpc/command_variable.cc +++ /dev/null @@ -1,169 +0,0 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2007, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#include "config.h" - -#include "parse.h" -#include "command_variable.h" - -namespace rpc { - -const torrent::Object -CommandVariable::set_bool(Command* rawCommand, target_type target, const torrent::Object& rawArgs) { - CommandVariable* variable = static_cast(rawCommand); - - const torrent::Object& arg = convert_to_single_argument(rawArgs); - - switch (arg.type()) { - case torrent::Object::TYPE_VALUE: - variable->m_variable = arg.as_value() ? (int64_t)1 : (int64_t)0; - break; - - case torrent::Object::TYPE_STRING: - // Move the checks into some is_true, is_false think in Command. - if (arg.as_string() == "yes" || arg.as_string() == "true") - variable->m_variable = (int64_t)1; - - else if (arg.as_string() == "no" || arg.as_string() == "false") - variable->m_variable = (int64_t)0; - - else - throw torrent::input_error("String does not parse as a boolean."); - - break; - - default: - throw torrent::input_error("Input is not a boolean."); - } - - return variable->m_variable; -} - -const torrent::Object -CommandVariable::get_bool(Command* rawCommand, target_type target, const torrent::Object& args) { - CommandVariable* variable = static_cast(rawCommand); - - return variable->m_variable; -} - -const torrent::Object -CommandVariable::set_value(Command* rawCommand, target_type target, const torrent::Object& rawArgs) { - CommandVariable* variable = static_cast(rawCommand); - - const torrent::Object& arg = convert_to_single_argument(rawArgs); - - switch (arg.type()) { - case torrent::Object::TYPE_NONE: - variable->m_variable = (int64_t)0; - break; - - case torrent::Object::TYPE_VALUE: - variable->m_variable = arg; - break; - - case torrent::Object::TYPE_STRING: - int64_t value; - parse_whole_value(arg.as_string().c_str(), &value, 0, 1); - - variable->m_variable = value; - break; - - default: - throw torrent::input_error("CommandValue unsupported type restriction."); - } - - return variable->m_variable; -} - -const torrent::Object -CommandVariable::get_value(Command* rawCommand, target_type target, const torrent::Object& args) { - CommandVariable* variable = static_cast(rawCommand); - - return variable->m_variable; -} - -const torrent::Object -CommandVariable::set_string(Command* rawCommand, target_type target, const torrent::Object& rawArgs) { - CommandVariable* variable = static_cast(rawCommand); - - const torrent::Object& arg = convert_to_single_argument(rawArgs); - - switch (arg.type()) { - case torrent::Object::TYPE_NONE: - variable->m_variable = std::string(); - break; - -// case torrent::Object::TYPE_VALUE: -// variable->m_variable = arg; -// break; - - case torrent::Object::TYPE_STRING: - variable->m_variable = arg; - break; - - default: - throw torrent::input_error("Not a string."); - } - - return variable->m_variable; -} - -const torrent::Object -CommandVariable::get_string(Command* rawCommand, target_type target, const torrent::Object& args) { - CommandVariable* variable = static_cast(rawCommand); - - return variable->m_variable; -} - -// -// ObjectPtr -// - -const torrent::Object -CommandObjectPtr::set_generic(Command* rawCommand, target_type target, const torrent::Object& rawArgs) { - CommandObjectPtr* command = static_cast(rawCommand); - - return (*command->m_object = rawArgs); -} - -const torrent::Object -CommandObjectPtr::get_generic(Command* rawCommand, target_type target, const torrent::Object& args) { - CommandObjectPtr* command = static_cast(rawCommand); - - return *command->m_object; -} - -} diff --git a/src/rpc/command_variable.h b/src/rpc/command_variable.h deleted file mode 100644 index 1cc89908..00000000 --- a/src/rpc/command_variable.h +++ /dev/null @@ -1,94 +0,0 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2007, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#ifndef RTORRENT_RPC_COMMAND_VARIABLES_H -#define RTORRENT_RPC_COMMAND_VARIABLES_H - -#include -#include -#include -#include - -#include "command.h" - -namespace rpc { - -class CommandVariable : public Command { -public: - CommandVariable(const torrent::Object& v = torrent::Object()) : m_variable(v) {} - - const torrent::Object variable() const { return m_variable; } - void set_variable(const torrent::Object& var) { m_variable = var; } - - static const torrent::Object set_bool(Command* rawCommand, target_type target, const torrent::Object& args); - static const torrent::Object get_bool(Command* rawCommand, target_type target, const torrent::Object& args); - - static const torrent::Object set_value(Command* rawCommand, target_type target, const torrent::Object& args); - static const torrent::Object get_value(Command* rawCommand, target_type target, const torrent::Object& args); - - static const torrent::Object set_string(Command* rawCommand, target_type target, const torrent::Object& args); - static const torrent::Object get_string(Command* rawCommand, target_type target, const torrent::Object& args); - -private: - torrent::Object m_variable; -}; - -class CommandObjectPtr : public Command { -public: - CommandObjectPtr(torrent::Object* obj = NULL) : m_object(obj) {} - - const torrent::Object* object() const { return m_object; } - void set_object(torrent::Object* obj) { m_object = obj; } - - static const torrent::Object set_generic(Command* rawCommand, target_type target, const torrent::Object& args); - static const torrent::Object get_generic(Command* rawCommand, target_type target, const torrent::Object& args); - -// static const torrent::Object set_bool(Command* rawCommand, target_type target, const torrent::Object& args); -// static const torrent::Object get_bool(Command* rawCommand, target_type target, const torrent::Object& args); - -// static const torrent::Object set_value(Command* rawCommand, target_type target, const torrent::Object& args); -// static const torrent::Object get_value(Command* rawCommand, target_type target, const torrent::Object& args); - -// static const torrent::Object set_string(Command* rawCommand, target_type target, const torrent::Object& args); -// static const torrent::Object get_string(Command* rawCommand, target_type target, const torrent::Object& args); - -private: - torrent::Object* m_object; -}; - -} - -#endif diff --git a/src/rpc/object_storage.cc b/src/rpc/object_storage.cc index c888bec3..27c7d45b 100644 --- a/src/rpc/object_storage.cc +++ b/src/rpc/object_storage.cc @@ -39,6 +39,7 @@ #include "object_storage.h" #include "parse.h" +#include "command_function.h" namespace rpc { @@ -54,14 +55,21 @@ object_storage::find_local(const torrent::raw_string& key) { } object_storage::iterator -object_storage::insert(const char* key_data, uint32_t key_size, const torrent::Object& object, unsigned int flags) { +object_storage::insert(const char* key_data, uint32_t key_size, const torrent::Object& rawObject, unsigned int flags) { if (std::find(key_data, key_data + key_size, '\0') != key_data + key_size) throw torrent::input_error("Found nul-char in string."); // Check for size > key_size. // Check for empty string. - // Ensure the object type is correct. + torrent::Object object; + + switch (flags & mask_type) { + case flag_bool_type: object = !!convert_to_value(rawObject); break; + case flag_value_type: object = convert_to_value(rawObject); break; + case flag_string_type: object = convert_to_string(rawObject); break; + case flag_function_type: object = convert_to_string(rawObject); break; + } if (!(flags & mask_type)) throw torrent::input_error("No type flags set when calling object_storage::insert."); @@ -71,8 +79,8 @@ object_storage::insert(const char* key_data, uint32_t key_size, const torrent::O if (!result.second) throw torrent::input_error("Key already exists in object_storage."); - result.first->second.object = object; result.first->second.flags = flags; + result.first->second.object = object; return result.first; } @@ -87,23 +95,67 @@ object_storage::get(const torrent::raw_string& key) { return itr->second.object; } +// const torrent::Object& +// object_storage::set(const torrent::raw_string& key, const torrent::Object& object) { +// local_iterator itr = find_local(key); + +// if (itr == end(bucket_count()) || (itr->second.flags & mask_type) != flag_generic_type) +// throw torrent::input_error("Key not found or wrong type."); + +// return itr->second.object = object; +// } + + const torrent::Object& -object_storage::set(const torrent::raw_string& key, const torrent::Object& object) { +object_storage::set_bool(const torrent::raw_string& key, int64_t object) { local_iterator itr = find_local(key); - if (itr == end(bucket_count())) - throw torrent::input_error("Key not found."); + if (itr == end(bucket_count()) || (itr->second.flags & mask_type) != flag_bool_type) + throw torrent::input_error("Key not found or wrong type."); - // Redo this... + return itr->second.object = !!object; +} - switch (itr->second.flags & mask_type) { - case flag_generic_type: itr->second.object = object; break; - case flag_value_type: itr->second.object = convert_to_value(object); break; - case flag_string_type: itr->second.object = convert_to_string(object); break; - default: throw torrent::internal_error("object_storage::set: Type not set."); - } - return itr->second.object; +const torrent::Object& +object_storage::set_value(const torrent::raw_string& key, int64_t object) { + local_iterator itr = find_local(key); + + if (itr == end(bucket_count()) || (itr->second.flags & mask_type) != flag_value_type) + throw torrent::input_error("Key not found or wrong type."); + + return itr->second.object = object; +} + + +const torrent::Object& +object_storage::set_string(const torrent::raw_string& key, const std::string& object) { + local_iterator itr = find_local(key); + + if (itr == end(bucket_count()) || (itr->second.flags & mask_type) != flag_string_type) + throw torrent::input_error("Key not found or wrong type."); + + return itr->second.object = object; +} + +const torrent::Object& +object_storage::set_function(const torrent::raw_string& key, const std::string& object) { + local_iterator itr = find_local(key); + + if (itr == end(bucket_count()) || (itr->second.flags & mask_type) != flag_function_type) + throw torrent::input_error("Key not found or wrong type."); + + return itr->second.object = object; +} + +torrent::Object +object_storage::call_function(const torrent::raw_string& key, target_type target, const torrent::Object& object) { + local_iterator itr = find_local(key); + + if (itr == end(bucket_count()) || !itr->second.object.is_string()) + throw torrent::input_error("Key not found or wrong type."); + + return command_function_call_str(itr->second.object.as_string(), target, object); } } diff --git a/src/rpc/object_storage.h b/src/rpc/object_storage.h index 8e7b3c3d..a96943a9 100644 --- a/src/rpc/object_storage.h +++ b/src/rpc/object_storage.h @@ -45,6 +45,8 @@ #include #include +#include "command.h" + namespace rpc { // The key size should be such that the value type size which includes @@ -150,31 +152,55 @@ public: using base_type::find; using base_type::erase; - static const unsigned int flag_generic_type = 0x1; - static const unsigned int flag_value_type = 0x2; - static const unsigned int flag_string_type = 0x4; - static const unsigned int flag_last_type = 0x8; + static const unsigned int flag_generic_type = 0x1; + static const unsigned int flag_bool_type = 0x2; + static const unsigned int flag_value_type = 0x3; + static const unsigned int flag_string_type = 0x4; + static const unsigned int flag_function_type = 0x5; - static const unsigned int mask_type = flag_last_type - 1; + static const unsigned int mask_type = 0xf; + + static const unsigned int flag_constant = 0x10; + static const unsigned int flag_static = 0x20; + static const unsigned int flag_private = 0x40; static const size_t key_size = key_type::max_size; local_iterator find_local(const torrent::raw_string& key); iterator insert(const char* key_data, uint32_t key_size, const torrent::Object& object, unsigned int flags); + iterator insert_c_str(const char* key, const torrent::Object& object, unsigned int flags) { return insert(key, std::strlen(key), object, flags); } iterator insert(const char* key, const torrent::Object& object, unsigned int flags); iterator insert(const torrent::raw_string& key, const torrent::Object& object, unsigned int flags); - iterator insert_string(const std::string& key, const torrent::Object& object, unsigned int flags); + iterator insert_str(const std::string& key, const torrent::Object& object, unsigned int flags); // Access functions that throw on error. const torrent::Object& get(const torrent::raw_string& key); - const torrent::Object& get_c_str(const char* str) { return get(torrent::raw_string(str, std::strlen(str))); } + const torrent::Object& get_c_str(const char* str) { return get(torrent::raw_string(str, std::strlen(str))); } + const torrent::Object& get_str(const std::string& str) { return get(torrent::raw_string(str.data(), str.size())); } - const torrent::Object& set(const torrent::raw_string& key, const torrent::Object& object); +// const torrent::Object& set(const torrent::raw_string& key, const torrent::Object& object); +// const torrent::Object& set_c_str(const char* str, const torrent::Object& object) { return set(torrent::raw_string(str, std::strlen(str)), object); } - const torrent::Object& set_c_str(const char* str, const torrent::Object& object) { return set(torrent::raw_string(str, std::strlen(str)), object); } + const torrent::Object& set_bool(const torrent::raw_string& key, int64_t object); + const torrent::Object& set_c_str_bool(const char* str, int64_t object) { return set_bool(torrent::raw_string::from_c_str(str), object); } + const torrent::Object& set_str_bool(const std::string& str, int64_t object) { return set_bool(torrent::raw_string::from_string(str), object); } + + const torrent::Object& set_value(const torrent::raw_string& key, int64_t object); + const torrent::Object& set_c_str_value(const char* str, int64_t object) { return set_value(torrent::raw_string::from_string(str), object); } + const torrent::Object& set_str_value(const std::string& str, int64_t object) { return set_value(torrent::raw_string::from_string(str), object); } + + const torrent::Object& set_string(const torrent::raw_string& key, const std::string& object); + const torrent::Object& set_c_str_string(const char* str, const std::string& object) { return set_string(torrent::raw_string::from_c_str(str), object); } + const torrent::Object& set_str_string(const std::string& str, const std::string& object) { return set_string(torrent::raw_string::from_string(str), object); } + + torrent::Object call_function(const torrent::raw_string& key, target_type target, const torrent::Object& object); + torrent::Object call_function_str(const std::string& key, target_type target, const torrent::Object& object); + + const torrent::Object& set_function(const torrent::raw_string& key, const std::string& object); + const torrent::Object& set_str_function(const std::string& str, const std::string& object) { return set_function(torrent::raw_string::from_string(str), object); } }; // @@ -227,10 +253,15 @@ object_storage::insert(const torrent::raw_string& key, const torrent::Object& ob } inline object_storage::iterator -object_storage::insert_string(const std::string& key, const torrent::Object& object, unsigned int flags) { +object_storage::insert_str(const std::string& key, const torrent::Object& object, unsigned int flags) { return insert(key.data(), key.size(), object, flags); } +inline torrent::Object +object_storage::call_function_str(const std::string& key, target_type target, const torrent::Object& object) { + return call_function(torrent::raw_string::from_string(key), target, object); +} + } #endif diff --git a/test/Makefile.am b/test/Makefile.am index 8e46aa31..3490ac0d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -18,6 +18,8 @@ rtorrentTest_SOURCES = \ rpc/command_slot_test.h \ rpc/object_storage_test.cc \ rpc/object_storage_test.h \ + src/command_dynamic_test.cc \ + src/command_dynamic_test.h \ main.cc rtorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS) diff --git a/test/rpc/object_storage_test.cc b/test/rpc/object_storage_test.cc index bf4bc179..fedac927 100644 --- a/test/rpc/object_storage_test.cc +++ b/test/rpc/object_storage_test.cc @@ -13,14 +13,14 @@ ObjectStorageTest::test_basics() { CPPUNIT_ASSERT(m_storage.empty()); - itr = m_storage.insert("test_1", torrent::Object("a"), rpc::object_storage::flag_generic_type); + itr = m_storage.insert("test_1", torrent::Object("a"), rpc::object_storage::flag_string_type); CPPUNIT_ASSERT(itr != m_storage.end()); CPPUNIT_ASSERT(&*itr != NULL); CPPUNIT_ASSERT(itr->first.size() == 6 && std::strcmp(itr->first.data(), "test_1") == 0); CPPUNIT_ASSERT(itr->second.object.is_string() && itr->second.object.as_string() == "a"); - ASSERT_CATCH_INPUT_ERROR( { m_storage.insert("test_1", torrent::Object("a"), rpc::object_storage::flag_generic_type); } ); + ASSERT_CATCH_INPUT_ERROR( { m_storage.insert("test_1", torrent::Object("a"), rpc::object_storage::flag_string_type); } ); // Test erase. m_storage.erase(rpc::object_storage::key_type::from_c_str("test_1")); @@ -35,13 +35,13 @@ ObjectStorageTest::test_basics() { void ObjectStorageTest::test_conversions() { - CPPUNIT_ASSERT(m_storage.insert("test_1", torrent::Object("a"), rpc::object_storage::flag_generic_type) != m_storage.end()); - CPPUNIT_ASSERT(m_storage.insert_string(std::string("test_2"), torrent::Object("a"), rpc::object_storage::flag_generic_type) != m_storage.end()); + CPPUNIT_ASSERT(m_storage.insert("test_1", torrent::Object("a"), rpc::object_storage::flag_string_type) != m_storage.end()); + CPPUNIT_ASSERT(m_storage.insert_str(std::string("test_2"), torrent::Object("a"), rpc::object_storage::flag_string_type) != m_storage.end()); char raw_3[8] = "test_3\x1"; torrent::raw_string raw_string_3(raw_3, 6); - CPPUNIT_ASSERT(m_storage.insert(raw_string_3, torrent::Object("a"), rpc::object_storage::flag_generic_type)->first == std::string("test_3")); + CPPUNIT_ASSERT(m_storage.insert(raw_string_3, torrent::Object("a"), rpc::object_storage::flag_string_type)->first == std::string("test_3")); m_storage.clear(); } @@ -49,7 +49,7 @@ void ObjectStorageTest::test_validate_keys() { torrent::raw_string raw_string_4("test_4\0foo", 10); - ASSERT_CATCH_INPUT_ERROR( { m_storage.insert(raw_string_4, torrent::Object("a"), rpc::object_storage::flag_generic_type); } ); + ASSERT_CATCH_INPUT_ERROR( { m_storage.insert(raw_string_4, torrent::Object("a"), rpc::object_storage::flag_string_type); } ); } // And test many other bad/good string combos. @@ -58,20 +58,20 @@ ObjectStorageTest::test_validate_keys() { void ObjectStorageTest::test_access() { - m_storage.insert("generic_1", torrent::Object("gen_a"), rpc::object_storage::flag_generic_type); + m_storage.insert("string_1", torrent::Object("gen_a"), rpc::object_storage::flag_string_type); m_storage.insert("value_1", int64_t(1), rpc::object_storage::flag_value_type); - CPPUNIT_ASSERT(m_storage.get_c_str("generic_1").as_string() == "gen_a"); - CPPUNIT_ASSERT(m_storage.set_c_str("generic_1", int64_t(1)).as_value() == 1); + CPPUNIT_ASSERT(m_storage.get_c_str("string_1").as_string() == "gen_a"); + CPPUNIT_ASSERT(m_storage.set_c_str_string("string_1", "test").as_string() == "test"); // Test value from raw and normal, list, etc. CPPUNIT_ASSERT(m_storage.get_c_str("value_1").as_value() == 1); - CPPUNIT_ASSERT(m_storage.set_c_str("value_1", int64_t(2)).as_value() == 2); - CPPUNIT_ASSERT(m_storage.set_c_str("value_1", "123").as_value() == 123); - CPPUNIT_ASSERT(m_storage.set_c_str("value_1", torrent::raw_string::from_c_str("321")).as_value() == 321); - // CPPUNIT_ASSERT(m_storage.set_c_str("value_1", torrent::raw_bencode::from_c_str("i567e")).as_value() == 567); - - ASSERT_CATCH_INPUT_ERROR( { m_storage.set_c_str("value_1", "e123"); } ); + CPPUNIT_ASSERT(m_storage.set_c_str_value("value_1", int64_t(2)).as_value() == 2); + // CPPUNIT_ASSERT(m_storage.set_c_str_value("value_1", "123").as_value() == 123); + // CPPUNIT_ASSERT(m_storage.set_c_str_value("value_1", torrent::raw_string::from_c_str("321")).as_value() == 321); + // CPPUNIT_ASSERT(m_storage.set_c_str_value("value_1", torrent::raw_bencode::from_c_str("i567e")).as_value() == 567); + + // ASSERT_CATCH_INPUT_ERROR( { m_storage.set_c_str_value("value_1", "e123"); } ); // Test string from raw and normal, list, etc. } diff --git a/test/src/command_dynamic_test.cc b/test/src/command_dynamic_test.cc new file mode 100644 index 00000000..675120f4 --- /dev/null +++ b/test/src/command_dynamic_test.cc @@ -0,0 +1,60 @@ +#include "config.h" + +#include + +#import "command_dynamic_test.h" + +#include "rpc/parse_commands.h" +#include "control.h" +#include "globals.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(CommandDynamicTest); + +#define ASSERT_CATCH_INPUT_ERROR(some_code) \ + try { some_code; CPPUNIT_ASSERT("torrent::input_error not caught" && false); } catch (torrent::input_error& e) { } + +void initialize_command_dynamic(); +void initialize_command_ui(); + +void +CommandDynamicTest::setUp() { + if (rpc::commands.empty()) { + setlocale(LC_ALL, ""); + cachedTime = rak::timer::current(); + control = new Control; + + initialize_command_dynamic(); + initialize_command_ui(); + } +} + +void +CommandDynamicTest::test_basics() { + rpc::commands.call_command("method.insert.value", rpc::create_object_list("test_basics.1", int64_t(1))); + CPPUNIT_ASSERT(rpc::commands.call_command("test_basics.1", torrent::Object()).as_value() == 1); +} + +void +CommandDynamicTest::test_get_set() { + rpc::commands.call_command("method.insert.simple", rpc::create_object_list("test_get_set.1", "cat=1")); + CPPUNIT_ASSERT(rpc::commands.call_command("test_get_set.1", torrent::Object()).as_string() == "1"); + CPPUNIT_ASSERT(rpc::commands.call_command("method.get", "test_get_set.1").as_string() == "cat=1"); + + rpc::commands.call_command("method.set", rpc::create_object_list("test_get_set.1", "cat=2")); + CPPUNIT_ASSERT(rpc::commands.call_command("method.get", "test_get_set.1").as_string() == "cat=2"); +} + +void +CommandDynamicTest::test_old_style() { + rpc::commands.call_command("method.insert", rpc::create_object_list("test_old_style.1", "value", int64_t(1))); + CPPUNIT_ASSERT(rpc::commands.call_command("test_old_style.1", torrent::Object()).as_value() == 1); + + rpc::commands.call_command("method.insert", rpc::create_object_list("test_old_style.2", "bool", int64_t(5))); + CPPUNIT_ASSERT(rpc::commands.call_command("test_old_style.2", torrent::Object()).as_value() == 1); + + rpc::commands.call_command("method.insert", rpc::create_object_list("test_old_style.3", "string", "test.2")); + CPPUNIT_ASSERT(rpc::commands.call_command("test_old_style.3", torrent::Object()).as_string() == "test.2"); + + rpc::commands.call_command("method.insert", rpc::create_object_list("test_old_style.4", "simple", "cat=test.3")); + CPPUNIT_ASSERT(rpc::commands.call_command("test_old_style.4", torrent::Object()).as_string() == "test.3"); +} diff --git a/test/src/command_dynamic_test.h b/test/src/command_dynamic_test.h new file mode 100644 index 00000000..4af0c66b --- /dev/null +++ b/test/src/command_dynamic_test.h @@ -0,0 +1,20 @@ +#include + +class CommandDynamicTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(CommandDynamicTest); + CPPUNIT_TEST(test_basics); + CPPUNIT_TEST(test_get_set); + CPPUNIT_TEST(test_old_style); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown() {} + + void test_basics(); + void test_get_set(); + + void test_old_style(); + +private: +};