mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-10 08:09:21 +00:00
* Added string, value and bool types to 'system.method.insert' for
storing variables. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1076 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+67
-20
@@ -41,6 +41,7 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "command_helpers.h"
|
#include "command_helpers.h"
|
||||||
|
#include "rpc/command_variable.h"
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
system_method_generate_command(torrent::Object::list_const_iterator first, torrent::Object::list_const_iterator last) {
|
system_method_generate_command(torrent::Object::list_const_iterator first, torrent::Object::list_const_iterator last) {
|
||||||
@@ -56,8 +57,23 @@ system_method_generate_command(torrent::Object::list_const_iterator first, torre
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <int postfix_size>
|
||||||
|
inline const char*
|
||||||
|
create_new_key(const std::string& key, const char postfix[postfix_size]) {
|
||||||
|
char *buffer = new char[key.size() + postfix_size];
|
||||||
|
std::memcpy(buffer, key.c_str(), key.size() + 1);
|
||||||
|
std::memcpy(buffer + key.size(), postfix, postfix_size);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
// system.method.insert <generic> {name, "simple|private|const", ...}
|
// system.method.insert <generic> {name, "simple|private|const", ...}
|
||||||
// system.method.insert <generic> {name, "list|private|const"}
|
// system.method.insert <generic> {name, "list|private|const"}
|
||||||
|
// system.method.insert <generic> {name, "value|private|const"}
|
||||||
|
// system.method.insert <generic> {name, "value|private|const", value}
|
||||||
|
// system.method.insert <generic> {name, "bool|private|const"}
|
||||||
|
// system.method.insert <generic> {name, "bool|private|const", bool}
|
||||||
|
// system.method.insert <generic> {name, "string|private|const"}
|
||||||
|
// system.method.insert <generic> {name, "string|private|const", string}
|
||||||
//
|
//
|
||||||
// Add a new user-defined method called 'name' and any number of
|
// Add a new user-defined method called 'name' and any number of
|
||||||
// lines.
|
// lines.
|
||||||
@@ -74,34 +90,65 @@ system_method_insert(__UNUSED rpc::target_type target, const torrent::Object& ra
|
|||||||
if (rawKey.empty() || rpc::commands.has(rawKey))
|
if (rawKey.empty() || rpc::commands.has(rawKey))
|
||||||
throw torrent::input_error("Invalid key.");
|
throw torrent::input_error("Invalid key.");
|
||||||
|
|
||||||
rpc::Command* command = NULL;
|
|
||||||
rpc::Command::any_slot slot = NULL;
|
|
||||||
int flags = rpc::CommandMap::flag_delete_key | rpc::CommandMap::flag_modifiable | rpc::CommandMap::flag_public_xmlrpc;
|
int flags = rpc::CommandMap::flag_delete_key | rpc::CommandMap::flag_modifiable | rpc::CommandMap::flag_public_xmlrpc;
|
||||||
|
|
||||||
const std::string& options = itrArgs->as_string();
|
const std::string& options = itrArgs->as_string();
|
||||||
|
|
||||||
// Use a | separated list of options here, for non-modifable,
|
|
||||||
// non-public methods, etc.
|
|
||||||
if (options.find("list") != std::string::npos) {
|
|
||||||
// Later, make it possible to add functions here.
|
|
||||||
slot = &rpc::CommandFunctionList::call;
|
|
||||||
command = new rpc::CommandFunctionList();
|
|
||||||
|
|
||||||
} else if (options.find("simple") != std::string::npos) {
|
|
||||||
slot = &rpc::CommandFunction::call;
|
|
||||||
command = new rpc::CommandFunction(system_method_generate_command(++itrArgs, args.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.find("private") != std::string::npos)
|
if (options.find("private") != std::string::npos)
|
||||||
flags &= ~rpc::CommandMap::flag_public_xmlrpc;
|
flags &= ~rpc::CommandMap::flag_public_xmlrpc;
|
||||||
|
|
||||||
if (options.find("const") != std::string::npos)
|
if (options.find("const") != std::string::npos)
|
||||||
flags &= ~rpc::CommandMap::flag_modifiable;
|
flags &= ~rpc::CommandMap::flag_modifiable;
|
||||||
|
|
||||||
char* key = new char[rawKey.size() + 1];
|
if (options.find("list") != std::string::npos) {
|
||||||
std::memcpy(key, rawKey.c_str(), rawKey.size() + 1);
|
// Later, make it possible to add functions here.
|
||||||
|
rpc::Command* command = new rpc::CommandFunctionList();
|
||||||
|
rpc::Command::any_slot slot = &rpc::CommandFunctionList::call;
|
||||||
|
|
||||||
|
rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, slot, flags, NULL, NULL);
|
||||||
|
|
||||||
|
} else if (options.find("simple") != std::string::npos) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
} else if (options.find("value") != std::string::npos ||
|
||||||
|
options.find("bool") != std::string::npos ||
|
||||||
|
options.find("string") != std::string::npos) {
|
||||||
|
rpc::CommandVariable *command;
|
||||||
|
rpc::Command::cleaned_slot getSlot;
|
||||||
|
rpc::Command::cleaned_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 {
|
||||||
|
command = new rpc::CommandVariable(std::string());
|
||||||
|
getSlot = &rpc::CommandVariable::get_string;
|
||||||
|
setSlot = &rpc::CommandVariable::set_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
rpc::commands.insert_type(create_new_key<5>(rawKey, ".set"), command, setSlot, flags | rpc::CommandMap::flag_dont_delete, NULL, NULL);
|
||||||
|
|
||||||
|
if (++itrArgs != args.end())
|
||||||
|
(*setSlot)(command, NULL, *itrArgs);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// THROW.
|
||||||
|
}
|
||||||
|
|
||||||
rpc::commands.insert_type(key, command, slot, flags, NULL, NULL);
|
|
||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +164,7 @@ system_method_erase(__UNUSED rpc::target_type target, const torrent::Object& raw
|
|||||||
if (itr == rpc::commands.end())
|
if (itr == rpc::commands.end())
|
||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
|
|
||||||
if (!(itr->second.m_flags & rpc::CommandMap::flag_modifiable))
|
if (!rpc::commands.is_modifiable(itr))
|
||||||
throw torrent::input_error("Command not modifiable.");
|
throw torrent::input_error("Command not modifiable.");
|
||||||
|
|
||||||
rpc::commands.erase(itr);
|
rpc::commands.erase(itr);
|
||||||
@@ -135,7 +182,7 @@ system_method_set(__UNUSED rpc::target_type target, const torrent::Object& rawAr
|
|||||||
rpc::CommandFunction* function;
|
rpc::CommandFunction* function;
|
||||||
rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str());
|
rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str());
|
||||||
|
|
||||||
if (itr == rpc::commands.end() || !(itr->second.m_flags & rpc::CommandMap::flag_modifiable) ||
|
if (!rpc::commands.is_modifiable(itr) ||
|
||||||
(function = dynamic_cast<rpc::CommandFunction*>(itr->second.m_variable)) == NULL)
|
(function = dynamic_cast<rpc::CommandFunction*>(itr->second.m_variable)) == NULL)
|
||||||
throw torrent::input_error("Command not modifiable or wrong type.");
|
throw torrent::input_error("Command not modifiable or wrong type.");
|
||||||
|
|
||||||
@@ -153,7 +200,7 @@ system_method_set_key(__UNUSED rpc::target_type target, const torrent::Object& r
|
|||||||
rpc::CommandFunctionList* function;
|
rpc::CommandFunctionList* function;
|
||||||
rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str());
|
rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str());
|
||||||
|
|
||||||
if (itr == rpc::commands.end() || !(itr->second.m_flags & rpc::CommandMap::flag_modifiable) ||
|
if (!rpc::commands.is_modifiable(itr) ||
|
||||||
(function = dynamic_cast<rpc::CommandFunctionList*>(itr->second.m_variable)) == NULL)
|
(function = dynamic_cast<rpc::CommandFunctionList*>(itr->second.m_variable)) == NULL)
|
||||||
throw torrent::input_error("Command not modifiable or wrong type.");
|
throw torrent::input_error("Command not modifiable or wrong type.");
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
rpc::parse_command_multiple
|
rpc::parse_command_multiple
|
||||||
(rpc::make_target(),
|
(rpc::make_target(),
|
||||||
|
// "system.method.insert = test.value,value\n"
|
||||||
|
// "system.method.insert = test.value2,value,6\n"
|
||||||
|
|
||||||
|
// "system.method.insert = test.string,string,6\n"
|
||||||
|
// "system.method.insert = test.bool,bool,true\n"
|
||||||
|
|
||||||
"system.method.insert = event.download.inserted,list\n"
|
"system.method.insert = event.download.inserted,list\n"
|
||||||
"system.method.insert = event.download.inserted_new,list\n"
|
"system.method.insert = event.download.inserted_new,list\n"
|
||||||
"system.method.insert = event.download.inserted_session,list\n"
|
"system.method.insert = event.download.inserted_session,list\n"
|
||||||
|
|||||||
@@ -49,6 +49,10 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "command_map.h"
|
#include "command_map.h"
|
||||||
|
|
||||||
|
// For XMLRPC stuff, clean up.
|
||||||
|
#include "xmlrpc.h"
|
||||||
|
#include "parse_commands.h"
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
CommandMap::~CommandMap() {
|
CommandMap::~CommandMap() {
|
||||||
@@ -73,6 +77,9 @@ CommandMap::insert(key_type key, Command* variable, int flags, const char* parm,
|
|||||||
if (itr != base_type::end())
|
if (itr != base_type::end())
|
||||||
throw torrent::internal_error("CommandMap::insert(...) tried to insert an already existing key.");
|
throw torrent::internal_error("CommandMap::insert(...) tried to insert an already existing key.");
|
||||||
|
|
||||||
|
if (rpc::xmlrpc.is_valid())
|
||||||
|
rpc::xmlrpc.insert_command(key, parm, doc);
|
||||||
|
|
||||||
return base_type::insert(itr, value_type(key, command_map_data_type(variable, flags, parm, doc)));
|
return base_type::insert(itr, value_type(key, command_map_data_type(variable, flags, parm, doc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ public:
|
|||||||
bool has(const char* key) const { return base_type::find(key) != base_type::end(); }
|
bool has(const char* key) const { return base_type::find(key) != base_type::end(); }
|
||||||
bool has(const std::string& key) const { return has(key.c_str()); }
|
bool has(const std::string& key) const { return has(key.c_str()); }
|
||||||
|
|
||||||
|
bool is_modifiable(const_iterator itr) { return itr != end() && (itr->second.m_flags & flag_modifiable); }
|
||||||
|
|
||||||
iterator insert(key_type key, Command* variable, int flags, const char* parm, const char* doc);
|
iterator insert(key_type key, Command* variable, int flags, const char* parm, const char* doc);
|
||||||
|
|
||||||
// Make this a wrapper call to insert without extra fluff.
|
// Make this a wrapper call to insert without extra fluff.
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ CommandVariable::set_string(Command* rawCommand, cleaned_type target, const torr
|
|||||||
|
|
||||||
switch (arg.type()) {
|
switch (arg.type()) {
|
||||||
case torrent::Object::TYPE_NONE:
|
case torrent::Object::TYPE_NONE:
|
||||||
variable->m_variable = std::string("");
|
variable->m_variable = std::string();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case torrent::Object::TYPE_VALUE:
|
// case torrent::Object::TYPE_VALUE:
|
||||||
|
|||||||
Reference in New Issue
Block a user