* Fix set_f_priority. Will require a call to update priorities.

* CommandMap::call_command(...) now uses a single function for all
calls using an integer id to figure out the object type.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@942 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-07-21 23:06:19 +00:00
parent 465625692f
commit e15aee3f77
7 changed files with 70 additions and 77 deletions
+29 -49
View File
@@ -71,19 +71,27 @@ CommandMap::insert(key_type key, Command* variable, int flags, const char* parm,
}
void
CommandMap::insert(key_type key, Command* variable, generic_slot genericSlot, download_slot downloadSlot, int flags,
const char* parm, const char* doc) {
CommandMap::insert_generic(key_type key, Command* variable, generic_slot targetSlot, int flags, const char* parm, const char* doc) {
iterator itr = insert(key, variable, flags, parm, doc);
itr->second.m_genericSlot = genericSlot;
itr->second.m_downloadSlot = downloadSlot;
itr->second.m_target = target_generic;
itr->second.m_genericSlot = targetSlot;
}
void
CommandMap::insert_file(key_type key, Command* variable, file_slot fileSlot, int flags, const char* parm, const char* doc) {
CommandMap::insert_download(key_type key, Command* variable, download_slot targetSlot, int flags, const char* parm, const char* doc) {
iterator itr = insert(key, variable, flags, parm, doc);
itr->second.m_fileSlot = fileSlot;
itr->second.m_target = target_download;
itr->second.m_downloadSlot = targetSlot;
}
void
CommandMap::insert_file(key_type key, Command* variable, file_slot targetSlot, int flags, const char* parm, const char* doc) {
iterator itr = insert(key, variable, flags, parm, doc);
itr->second.m_target = target_file;
itr->second.m_fileSlot = targetSlot;
}
void
@@ -95,61 +103,33 @@ CommandMap::insert(key_type key, const command_map_data_type src) {
itr = base_type::insert(itr, value_type(key, command_map_data_type(src.m_variable, src.m_flags | flag_dont_delete, src.m_parm, src.m_doc)));
itr->second.m_genericSlot = src.m_genericSlot;
itr->second.m_downloadSlot = src.m_downloadSlot;
itr->second.m_fileSlot = src.m_fileSlot;
}
itr->second.m_target = src.m_target;
// These should really be handled by a single function. An type enum
// passed with the object would work, and the switch would probably be
// optimized away as the type difference is not reflected in the
// member function pointer call.
const CommandMap::mapped_type
CommandMap::call_command(key_type key, const mapped_type& arg) {
const_iterator itr = base_type::find(key);
if (itr == base_type::end())
throw torrent::input_error("Command \"" + std::string(key) + "\" does not exist.");
if (itr->second.m_genericSlot == NULL)
throw torrent::input_error("Command does not have a generic slot.");
return itr->second.m_genericSlot(itr->second.m_variable, arg);
}
const CommandMap::mapped_type
CommandMap::call_command_d(key_type key, core::Download* download, const mapped_type& arg) {
const_iterator itr = base_type::find(key);
if (itr == base_type::end())
throw torrent::input_error("Command \"" + std::string(key) + "\" does not exist.");
if (itr->second.m_downloadSlot == NULL || download == NULL) {
if (itr->second.m_genericSlot == NULL)
throw torrent::input_error("Command does not have a generic slot.");
return itr->second.m_genericSlot(itr->second.m_variable, arg);
switch (itr->second.m_target) {
case target_generic: itr->second.m_genericSlot = src.m_genericSlot; break;
case target_download: itr->second.m_downloadSlot = src.m_downloadSlot; break;
case target_file: itr->second.m_fileSlot = src.m_fileSlot; break;
default: throw torrent::internal_error("CommandMap::insert(...) Invalid target.");
}
return itr->second.m_downloadSlot(itr->second.m_variable, download, arg);
}
const CommandMap::mapped_type
CommandMap::call_command_f(key_type key, torrent::File* file, const mapped_type& arg) {
CommandMap::call_command(key_type key, const mapped_type& arg, target_type target) {
const_iterator itr = base_type::find(key);
if (itr == base_type::end())
throw torrent::input_error("Command \"" + std::string(key) + "\" does not exist.");
if (itr->second.m_fileSlot == NULL || file == NULL) {
if (itr->second.m_genericSlot == NULL)
throw torrent::input_error("Command does not have a generic slot.");
if ((itr->second.m_target != target.first && itr->second.m_target != target_generic) ||
(itr->second.m_target != target_generic && target.second == NULL))
throw torrent::input_error("Command type mis-match.");
return itr->second.m_genericSlot(itr->second.m_variable, arg);
switch (itr->second.m_target) {
case target_generic: return itr->second.m_genericSlot(itr->second.m_variable, arg);
case target_download: return itr->second.m_downloadSlot(itr->second.m_variable, (core::Download*)target.second, arg);
case target_file: return itr->second.m_fileSlot(itr->second.m_variable, (torrent::File*)target.second, arg);
default: throw torrent::internal_error("CommandMap::call_command(...) Invalid target.");
}
return itr->second.m_fileSlot(itr->second.m_variable, file, arg);
}
}
+19 -14
View File
@@ -67,18 +67,18 @@ struct command_map_data_type {
typedef const torrent::Object (*file_slot)(Command*, torrent::File*, const torrent::Object&);
command_map_data_type(Command* variable, int flags, const char* parm, const char* doc) :
m_variable(variable), m_genericSlot(NULL), m_downloadSlot(NULL), m_fileSlot(NULL),
m_flags(flags), m_parm(parm), m_doc(doc) {}
m_variable(variable), m_flags(flags), m_parm(parm), m_doc(doc) {}
Command* m_variable;
// Should make this into a union and pass a type id when calling
// commands, making it all use the same generic interface.
generic_slot m_genericSlot;
download_slot m_downloadSlot;
file_slot m_fileSlot;
union {
generic_slot m_genericSlot;
download_slot m_downloadSlot;
file_slot m_fileSlot;
};
int m_flags;
int m_target;
const char* m_parm;
const char* m_doc;
@@ -103,6 +103,12 @@ public:
using base_type::end;
using base_type::find;
typedef std::pair<int, void*> target_type;
static const int target_generic = 0;
static const int target_download = 1;
static const int target_file = 2;
static const int flag_dont_delete = 0x1;
static const int flag_public_xmlrpc = 0x2;
@@ -114,16 +120,15 @@ public:
iterator insert(key_type key, Command* variable, int flags, const char* parm, const char* doc);
void insert(key_type key, Command* variable, generic_slot genericSlot, download_slot downloadSlot, int flags,
const char* parm, const char* doc);
void insert_file(key_type key, Command* variable, file_slot fileSlot, int flags, const char* parm, const char* doc);
void insert_generic(key_type key, Command* variable, generic_slot targetSlot, int flags, const char* parm, const char* doc);
void insert_download(key_type key, Command* variable, download_slot targetSlot, int flags, const char* parm, const char* doc);
void insert_file(key_type key, Command* variable, file_slot targetSlot, int flags, const char* parm, const char* doc);
void insert(key_type key, const command_map_data_type src);
const mapped_type call_command(key_type key, const mapped_type& arg);
const mapped_type call_command_d(key_type key, core::Download* download, const mapped_type& arg);
const mapped_type call_command_f(key_type key, torrent::File* file, const mapped_type& arg);
const mapped_type call_command(key_type key, const mapped_type& arg, target_type target = target_type((int)target_generic, NULL));
const mapped_type call_command_d(key_type key, core::Download* download, const mapped_type& arg) { return call_command(key, arg, target_type((int)target_download, download)); }
const mapped_type call_command_f(key_type key, torrent::File* file, const mapped_type& arg) { return call_command(key, arg, target_type((int)target_file, file)); }
private:
CommandMap(const CommandMap&);
+2 -2
View File
@@ -502,10 +502,10 @@ XmlRpc::set_dialect(int dialect) {
void XmlRpc::initialize() { throw torrent::resource_error("XMLRPC not supported."); }
void XmlRpc::cleanup() {}
void XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool onDownload) {}
void XmlRpc::insert_command(__UNUSED const char* name, __UNUSED const char* parm, __UNUSED const char* doc, __UNUSED int call) {}
void XmlRpc::set_dialect(__UNUSED int dialect) {}
bool XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) { return false; }
bool XmlRpc::process(__UNUSED const char* inBuffer, __UNUSED uint32_t length, __UNUSED slot_write slotWrite) { return false; }
#endif