mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-21 16:46:18 +00:00
* Added 'argument.?' commands that passing of arguments to commands
created with 'system.method.insert'. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1077 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -49,6 +49,8 @@ rpc::CommandSlot<void> commandSlots[COMMAND_SLOTS_SIZE];
|
|||||||
rpc::CommandSlot<void>* commandSlotsItr = commandSlots;
|
rpc::CommandSlot<void>* commandSlotsItr = commandSlots;
|
||||||
rpc::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE];
|
rpc::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE];
|
||||||
rpc::CommandVariable* commandVariablesItr = commandVariables;
|
rpc::CommandVariable* commandVariablesItr = commandVariables;
|
||||||
|
rpc::CommandObjectPtr commandObjectPtrs[COMMAND_OBJECT_PTR_SIZE];
|
||||||
|
rpc::CommandObjectPtr* commandObjectPtrsItr = commandObjectPtrs;
|
||||||
rpc::CommandSlot<core::Download*> commandDownloadSlots[COMMAND_DOWNLOAD_SLOTS_SIZE];
|
rpc::CommandSlot<core::Download*> commandDownloadSlots[COMMAND_DOWNLOAD_SLOTS_SIZE];
|
||||||
rpc::CommandSlot<core::Download*>* commandDownloadSlotsItr = commandDownloadSlots;
|
rpc::CommandSlot<core::Download*>* commandDownloadSlotsItr = commandDownloadSlots;
|
||||||
rpc::CommandSlot<torrent::File*> commandFileSlots[COMMAND_FILE_SLOTS_SIZE];
|
rpc::CommandSlot<torrent::File*> commandFileSlots[COMMAND_FILE_SLOTS_SIZE];
|
||||||
@@ -89,6 +91,7 @@ initialize_commands() {
|
|||||||
#ifdef ADDING_COMMANDS
|
#ifdef ADDING_COMMANDS
|
||||||
if (commandSlotsItr > commandSlots + COMMAND_SLOTS_SIZE ||
|
if (commandSlotsItr > commandSlots + COMMAND_SLOTS_SIZE ||
|
||||||
commandVariablesItr > commandVariables + COMMAND_VARIABLES_SIZE ||
|
commandVariablesItr > commandVariables + COMMAND_VARIABLES_SIZE ||
|
||||||
|
commandObjectPtrsItr > commandObjectPtrs + COMMAND_OBJECT_PTR_SIZE ||
|
||||||
commandDownloadSlotsItr > commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE ||
|
commandDownloadSlotsItr > commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE ||
|
||||||
commandFileSlotsItr > commandFileSlots + COMMAND_FILE_SLOTS_SIZE ||
|
commandFileSlotsItr > commandFileSlots + COMMAND_FILE_SLOTS_SIZE ||
|
||||||
commandFileItrSlotsItr > commandFileItrSlots + COMMAND_FILE_ITR_SLOTS_SIZE ||
|
commandFileItrSlotsItr > commandFileItrSlots + COMMAND_FILE_ITR_SLOTS_SIZE ||
|
||||||
@@ -98,6 +101,7 @@ initialize_commands() {
|
|||||||
#else
|
#else
|
||||||
if (commandSlotsItr != commandSlots + COMMAND_SLOTS_SIZE ||
|
if (commandSlotsItr != commandSlots + COMMAND_SLOTS_SIZE ||
|
||||||
commandVariablesItr != commandVariables + COMMAND_VARIABLES_SIZE ||
|
commandVariablesItr != commandVariables + COMMAND_VARIABLES_SIZE ||
|
||||||
|
commandObjectPtrsItr != commandObjectPtrs + COMMAND_OBJECT_PTR_SIZE ||
|
||||||
commandDownloadSlotsItr != commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE ||
|
commandDownloadSlotsItr != commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE ||
|
||||||
commandFileSlotsItr != commandFileSlots + COMMAND_FILE_SLOTS_SIZE ||
|
commandFileSlotsItr != commandFileSlots + COMMAND_FILE_SLOTS_SIZE ||
|
||||||
commandFileItrSlotsItr != commandFileItrSlots + COMMAND_FILE_ITR_SLOTS_SIZE ||
|
commandFileItrSlotsItr != commandFileItrSlots + COMMAND_FILE_ITR_SLOTS_SIZE ||
|
||||||
|
|||||||
@@ -43,12 +43,14 @@
|
|||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
class CommandVariable;
|
class CommandVariable;
|
||||||
|
class CommandObjectPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// By using a static array we avoid allocating the variables on the
|
// By using a static array we avoid allocating the variables on the
|
||||||
// heap. This should reduce memory use and improve cache locality.
|
// heap. This should reduce memory use and improve cache locality.
|
||||||
#define COMMAND_SLOTS_SIZE 200
|
#define COMMAND_SLOTS_SIZE 200
|
||||||
#define COMMAND_VARIABLES_SIZE 100
|
#define COMMAND_VARIABLES_SIZE 100
|
||||||
|
#define COMMAND_OBJECT_PTR_SIZE 20
|
||||||
#define COMMAND_DOWNLOAD_SLOTS_SIZE 150
|
#define COMMAND_DOWNLOAD_SLOTS_SIZE 150
|
||||||
#define COMMAND_FILE_SLOTS_SIZE 30
|
#define COMMAND_FILE_SLOTS_SIZE 30
|
||||||
#define COMMAND_FILE_ITR_SLOTS_SIZE 10
|
#define COMMAND_FILE_ITR_SLOTS_SIZE 10
|
||||||
@@ -62,6 +64,8 @@ extern rpc::CommandSlot<void> commandSlots[COMMAND_SLOTS_SIZE];
|
|||||||
extern rpc::CommandSlot<void>* commandSlotsItr;
|
extern rpc::CommandSlot<void>* commandSlotsItr;
|
||||||
extern rpc::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE];
|
extern rpc::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE];
|
||||||
extern rpc::CommandVariable* commandVariablesItr;
|
extern rpc::CommandVariable* commandVariablesItr;
|
||||||
|
extern rpc::CommandObjectPtr commandObjectPtrs[COMMAND_OBJECT_PTR_SIZE];
|
||||||
|
extern rpc::CommandObjectPtr* commandObjectPtrsItr;
|
||||||
extern rpc::CommandSlot<core::Download*> commandDownloadSlots[COMMAND_DOWNLOAD_SLOTS_SIZE];
|
extern rpc::CommandSlot<core::Download*> commandDownloadSlots[COMMAND_DOWNLOAD_SLOTS_SIZE];
|
||||||
extern rpc::CommandSlot<core::Download*>* commandDownloadSlotsItr;
|
extern rpc::CommandSlot<core::Download*>* commandDownloadSlotsItr;
|
||||||
extern rpc::CommandSlot<torrent::File*> commandFileSlots[COMMAND_FILE_SLOTS_SIZE];
|
extern rpc::CommandSlot<torrent::File*> commandFileSlots[COMMAND_FILE_SLOTS_SIZE];
|
||||||
@@ -220,4 +224,8 @@ add_variable(key, NULL, NULL, &rpc::CommandVariable::get_string, NULL, std::stri
|
|||||||
#define CMD_FUNC_SINGLE(key, command) \
|
#define CMD_FUNC_SINGLE(key, command) \
|
||||||
rpc::commands.insert_type(key, new rpc::CommandFunction(command), &rpc::CommandFunction::call, rpc::CommandMap::flag_public_xmlrpc, NULL, NULL);
|
rpc::commands.insert_type(key, new rpc::CommandFunction(command), &rpc::CommandFunction::call, rpc::CommandMap::flag_public_xmlrpc, NULL, NULL);
|
||||||
|
|
||||||
|
#define CMD_OBJ_P(key, function, target) \
|
||||||
|
commandObjectPtrsItr->set_object(target); \
|
||||||
|
rpc::commands.insert_type(key, commandObjectPtrsItr++, &rpc::CommandObjectPtr::function, rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, NULL, NULL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -169,4 +169,13 @@ initialize_command_local() {
|
|||||||
ADD_COMMAND_LIST("execute_raw_nothrow", rak::bind2_mem_fn(&rpc::execFile, &rpc::ExecFile::execute_object, 0));
|
ADD_COMMAND_LIST("execute_raw_nothrow", rak::bind2_mem_fn(&rpc::execFile, &rpc::ExecFile::execute_object, 0));
|
||||||
|
|
||||||
ADD_COMMAND_STRING_UN("execute_log", std::ptr_fun(&apply_execute_log));
|
ADD_COMMAND_STRING_UN("execute_log", std::ptr_fun(&apply_execute_log));
|
||||||
|
|
||||||
|
*rpc::Command::argument(0) = "placeholder.0";
|
||||||
|
*rpc::Command::argument(1) = "placeholder.1";
|
||||||
|
*rpc::Command::argument(2) = "placeholder.2";
|
||||||
|
*rpc::Command::argument(3) = "placeholder.3";
|
||||||
|
CMD_OBJ_P("argument.0", get_generic, rpc::Command::argument(0));
|
||||||
|
CMD_OBJ_P("argument.1", get_generic, rpc::Command::argument(1));
|
||||||
|
CMD_OBJ_P("argument.2", get_generic, rpc::Command::argument(2));
|
||||||
|
CMD_OBJ_P("argument.3", get_generic, rpc::Command::argument(3));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ main(int argc, char** argv) {
|
|||||||
// "system.method.insert = test.string,string,6\n"
|
// "system.method.insert = test.string,string,6\n"
|
||||||
// "system.method.insert = test.bool,bool,true\n"
|
// "system.method.insert = test.bool,bool,true\n"
|
||||||
|
|
||||||
|
"system.method.insert = test.method.simple,simple,\"print=simple_test_,$argument.0=\"\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"
|
||||||
|
|||||||
@@ -132,9 +132,18 @@ public:
|
|||||||
Command() {}
|
Command() {}
|
||||||
virtual ~Command() {}
|
virtual ~Command() {}
|
||||||
|
|
||||||
|
static torrent::Object* argument(unsigned int index) { return m_arguments + index; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Command(const Command&);
|
Command(const Command&);
|
||||||
void operator = (const Command&);
|
void operator = (const Command&);
|
||||||
|
|
||||||
|
// For use by functions that need to use placeholders to arguments
|
||||||
|
// within commands. E.d. callable command strings where one of the
|
||||||
|
// arguments within the command needs to be supplied by the caller.
|
||||||
|
static const unsigned int max_arguments = 10;
|
||||||
|
|
||||||
|
static torrent::Object m_arguments[max_arguments];
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T1 = void, typename T2 = void>
|
template <typename T1 = void, typename T2 = void>
|
||||||
|
|||||||
@@ -48,20 +48,66 @@ namespace rpc {
|
|||||||
|
|
||||||
const torrent::Object
|
const torrent::Object
|
||||||
CommandFunction::call(Command* rawCommand, target_type target, const torrent::Object& args) {
|
CommandFunction::call(Command* rawCommand, target_type target, const torrent::Object& args) {
|
||||||
|
char* buffer[sizeof(torrent::Object) * Command::max_arguments];
|
||||||
|
torrent::Object* stack = (torrent::Object*)buffer;
|
||||||
|
torrent::Object* first = (torrent::Object*)buffer;
|
||||||
|
|
||||||
|
if (args.is_list()) {
|
||||||
|
// Do nothing for now.
|
||||||
|
for (torrent::Object::list_const_iterator itr = args.as_list().begin(), last = args.as_list().end();
|
||||||
|
itr != last && first != stack + Command::max_arguments;
|
||||||
|
itr++, first++) {
|
||||||
|
new (first) torrent::Object(*itr);
|
||||||
|
first->swap(*argument(std::distance(stack, first)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (args.type() != torrent::Object::TYPE_NONE) {
|
||||||
|
new (first) torrent::Object(args);
|
||||||
|
(first++)->swap(*argument(0));
|
||||||
|
}
|
||||||
|
|
||||||
CommandFunction* command = reinterpret_cast<CommandFunction*>(rawCommand);
|
CommandFunction* command = reinterpret_cast<CommandFunction*>(rawCommand);
|
||||||
|
|
||||||
parse_command_multiple(target, command->m_command.c_str(), command->m_command.c_str() + command->m_command.size());
|
parse_command_multiple(target, command->m_command.c_str(), command->m_command.c_str() + command->m_command.size());
|
||||||
|
|
||||||
|
while (first-- != stack) {
|
||||||
|
first->swap(*argument(std::distance(stack, first)));
|
||||||
|
first->~Object();
|
||||||
|
}
|
||||||
|
|
||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
const torrent::Object
|
const torrent::Object
|
||||||
CommandFunctionList::call(Command* rawCommand, target_type target, const torrent::Object& args) {
|
CommandFunctionList::call(Command* rawCommand, target_type target, const torrent::Object& args) {
|
||||||
|
char* buffer[sizeof(torrent::Object) * Command::max_arguments];
|
||||||
|
torrent::Object* stack = (torrent::Object*)buffer;
|
||||||
|
torrent::Object* first = (torrent::Object*)buffer;
|
||||||
|
|
||||||
|
if (args.is_list()) {
|
||||||
|
// Do nothing for now.
|
||||||
|
for (torrent::Object::list_const_iterator itr = args.as_list().begin(), last = args.as_list().end();
|
||||||
|
itr != last && first != stack + Command::max_arguments;
|
||||||
|
itr++, first++) {
|
||||||
|
new (first) torrent::Object(*itr);
|
||||||
|
first->swap(*argument(std::distance(stack, first)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (args.type() != torrent::Object::TYPE_NONE) {
|
||||||
|
new (first) torrent::Object(args);
|
||||||
|
(first++)->swap(*argument(0));
|
||||||
|
}
|
||||||
|
|
||||||
CommandFunctionList* command = reinterpret_cast<CommandFunctionList*>(rawCommand);
|
CommandFunctionList* command = reinterpret_cast<CommandFunctionList*>(rawCommand);
|
||||||
|
|
||||||
for (base_type::const_iterator itr = command->begin(), last = command->end(); itr != last; itr++)
|
for (base_type::const_iterator itr = command->begin(), last = command->end(); itr != last; itr++)
|
||||||
parse_command_multiple(target, itr->second.c_str(), itr->second.c_str() + itr->second.size());
|
parse_command_multiple(target, itr->second.c_str(), itr->second.c_str() + itr->second.size());
|
||||||
|
|
||||||
|
while (first-- != stack) {
|
||||||
|
first->swap(*argument(std::distance(stack, first)));
|
||||||
|
first->~Object();
|
||||||
|
}
|
||||||
|
|
||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,8 @@
|
|||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
|
torrent::Object Command::m_arguments[Command::max_arguments];
|
||||||
|
|
||||||
CommandMap::~CommandMap() {
|
CommandMap::~CommandMap() {
|
||||||
std::vector<const char*> keys;
|
std::vector<const char*> keys;
|
||||||
|
|
||||||
|
|||||||
@@ -148,4 +148,22 @@ CommandVariable::get_string(Command* rawCommand, cleaned_type target, const torr
|
|||||||
return variable->m_variable;
|
return variable->m_variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ObjectPtr
|
||||||
|
//
|
||||||
|
|
||||||
|
const torrent::Object
|
||||||
|
CommandObjectPtr::set_generic(Command* rawCommand, cleaned_type target, const torrent::Object& rawArgs) {
|
||||||
|
CommandObjectPtr* command = static_cast<CommandObjectPtr*>(rawCommand);
|
||||||
|
|
||||||
|
return (*command->m_object = rawArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const torrent::Object
|
||||||
|
CommandObjectPtr::get_generic(Command* rawCommand, cleaned_type target, const torrent::Object& args) {
|
||||||
|
CommandObjectPtr* command = static_cast<CommandObjectPtr*>(rawCommand);
|
||||||
|
|
||||||
|
return *command->m_object;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,31 @@ private:
|
|||||||
torrent::Object m_variable;
|
torrent::Object m_variable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CommandObjectPtr : public Command {
|
||||||
|
public:
|
||||||
|
typedef target_wrapper<void>::cleaned_type cleaned_type;
|
||||||
|
|
||||||
|
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, cleaned_type target, const torrent::Object& args);
|
||||||
|
static const torrent::Object get_generic(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
|
||||||
|
// static const torrent::Object set_bool(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
// static const torrent::Object get_bool(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
|
||||||
|
// static const torrent::Object set_value(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
// static const torrent::Object get_value(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
|
||||||
|
// static const torrent::Object set_string(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
// static const torrent::Object get_string(Command* rawCommand, cleaned_type target, const torrent::Object& args);
|
||||||
|
|
||||||
|
private:
|
||||||
|
torrent::Object* m_object;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user