* Added 'method.const' and 'method.const.enable' for setting the const flag for objects in object_storage.

* Added '<foo_list>.push_back' to all list objects in object_storage.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1242 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2011-06-22 06:13:43 +00:00
parent 90582b58c3
commit d0d52cdda1
5 changed files with 127 additions and 92 deletions
+9 -4
View File
@@ -303,6 +303,8 @@ system_method_insert(const torrent::Object::list_type& args) {
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("list") != std::string::npos)
new_flags = rpc::object_storage::flag_list_type;
else if (options.find("simple") != std::string::npos)
new_flags = rpc::object_storage::flag_function_type;
else
@@ -428,10 +430,8 @@ initialize_command_dynamic() {
CMD2_VAR_BOOL ("method.use_deprecated", true);
CMD2_VAR_VALUE ("method.use_intermediate", 1);
CMD2_ANY_LIST ("method.insert", std::bind(&system_method_insert, std::placeholders::_2));
CMD2_ANY_LIST ("method.insert.value", std::bind(&system_method_insert_object, std::placeholders::_2,
rpc::object_storage::flag_value_type));
CMD2_ANY_LIST ("method.insert", std::bind(&system_method_insert, std::placeholders::_2));
CMD2_ANY_LIST ("method.insert.value", std::bind(&system_method_insert_object, std::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);
@@ -444,6 +444,11 @@ initialize_command_dynamic() {
std::placeholders::_2));
CMD2_ANY_LIST ("method.set", std::bind(&system_method_set_function, std::placeholders::_2));
CMD2_ANY_STRING ("method.const", std::bind(&rpc::object_storage::has_flag_str, control->object_storage(),
std::placeholders::_2, rpc::object_storage::flag_constant));
CMD2_ANY_STRING_V("method.const.enable", std::bind(&rpc::object_storage::enable_flag_str, control->object_storage(),
std::placeholders::_2, rpc::object_storage::flag_constant));
CMD2_ANY_LIST ("method.has_key", std::bind(&system_method_has_key, std::placeholders::_2));
CMD2_ANY_LIST ("method.set_key", std::bind(&system_method_set_key, std::placeholders::_2));
CMD2_ANY_STRING ("method.list_keys", std::bind(&system_method_list_keys, std::placeholders::_2));
+4 -1
View File
@@ -58,6 +58,7 @@ void initialize_commands();
#define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, slot, "i:", "")
#define CMD2_ANY_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call<rpc::target_type>, slot, "i:", "")
#define CMD2_ANY_VOID(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, object_convert_void(slot), "i:", "")
#define CMD2_ANY_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, object_convert_void(slot), "i:", "")
#define CMD2_ANY_L(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, slot, "A:", "")
@@ -127,7 +128,9 @@ void initialize_commands();
CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
torrent::raw_string::from_c_str(key))); \
CMD2_ANY_LIST(key ".set", std::bind(&rpc::object_storage::set_list, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2));
torrent::raw_string::from_c_str(key), std::placeholders::_2)); \
CMD2_ANY_VOID(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2));
#define CMD2_FUNC_SINGLE(key, cmds) \
CMD2_ANY(key, std::bind(&rpc::command_function_call, torrent::raw_string::from_c_str(cmds), \
+47 -41
View File
@@ -46,6 +46,7 @@
#include "exec_file.h"
#include "parse.h"
#include "thread_base.h"
namespace rpc {
@@ -107,57 +108,62 @@ ExecFile::execute(const char* file, char* const* argv, int flags) {
int result = execvp(file, argv);
_exit(result);
}
} else {
if (flags & flag_capture) {
m_capture = std::string();
::close(pipeFd[1]);
char buffer[4096];
ssize_t length;
do {
length = read(pipeFd[0], buffer, sizeof(buffer));
if (length > 0)
m_capture += std::string(buffer, length);
} while (length > 0);
::close(pipeFd[0]);
if (m_logFd != -1) {
write(m_logFd, "Captured output:\n", sizeof("Captured output:\n"));
write(m_logFd, m_capture.data(), m_capture.length());
}
}
if (flags & flag_background) {
if (m_logFd != -1)
write(m_logFd, "\n--- Background task ---\n", sizeof("\n--- Background task ---\n"));
if (flags & flag_background) {
if (m_logFd != -1)
write(m_logFd, "\n--- Background task ---\n", sizeof("\n--- Background task ---\n"));
return 0;
}
return 0;
}
int status;
int wpid;
// We yield the global lock when waiting for the executed command to
// finish so that XMLRPC and other threads can continue working.
ThreadBase::release_global_lock();
if (flags & flag_capture) {
m_capture = std::string();
::close(pipeFd[1]);
char buffer[4096];
ssize_t length;
do {
wpid = waitpid(childPid, &status, 0);
} while (wpid == -1 && rak::error_number::current().value() == rak::error_number::e_intr);
length = read(pipeFd[0], buffer, sizeof(buffer));
if (wpid != childPid)
throw torrent::internal_error("ExecFile::execute(...) waitpid failed.");
if (length > 0)
m_capture += std::string(buffer, length);
} while (length > 0);
::close(pipeFd[0]);
// Check return value?
if (m_logFd != -1) {
if (status == 0)
write(m_logFd, "\n--- Success ---\n", sizeof("\n--- Success ---\n"));
else
write(m_logFd, "\n--- Error ---\n", sizeof("\n--- Error ---\n"));
write(m_logFd, "Captured output:\n", sizeof("Captured output:\n"));
write(m_logFd, m_capture.data(), m_capture.length());
}
return status;
}
int status;
int wpid;
do {
wpid = waitpid(childPid, &status, 0);
} while (wpid == -1 && rak::error_number::current().value() == rak::error_number::e_intr);
ThreadBase::acquire_global_lock();
if (wpid != childPid)
throw torrent::internal_error("ExecFile::execute(...) waitpid failed.");
// Check return value?
if (m_logFd != -1) {
if (status == 0)
write(m_logFd, "\n--- Success ---\n", sizeof("\n--- Success ---\n"));
else
write(m_logFd, "\n--- Error ---\n", sizeof("\n--- Error ---\n"));
}
return status;
}
torrent::Object
+56 -46
View File
@@ -55,6 +55,33 @@ object_storage::find_local(const torrent::raw_string& key) {
return end(bucket_count());
}
object_storage::local_iterator
object_storage::find_local_const(const torrent::raw_string& key, unsigned int type) {
local_iterator itr = find_local(key);
if (itr == end(bucket_count()))
throw torrent::input_error("Key not found.");
if ((type != 0 && (itr->second.flags & mask_type) != type))
throw torrent::input_error("Object is wrong type or const.");
return itr;
}
object_storage::local_iterator
object_storage::find_local_mutable(const torrent::raw_string& key, unsigned int type) {
local_iterator itr = find_local(key);
if (itr == end(bucket_count()))
throw torrent::input_error("Key not found.");
if ((type != 0 && (itr->second.flags & mask_type) != type) ||
itr->second.flags & flag_constant)
throw torrent::input_error("Object is wrong type or const.");
return itr;
}
object_storage::iterator
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)
@@ -92,74 +119,65 @@ object_storage::insert(const char* key_data, uint32_t key_size, const torrent::O
return result.first;
}
bool
object_storage::has_flag(const torrent::raw_string& key, unsigned int flag) {
local_iterator itr = find_local_const(key);
return itr->second.flags & flag;
}
void
object_storage::enable_flag(const torrent::raw_string& key, unsigned int flag) {
local_iterator itr = find_local_mutable(key);
itr->second.flags |= (flag & (flag_constant));
}
const torrent::Object&
object_storage::get(const torrent::raw_string& key) {
local_iterator itr = find_local(key);
if (itr == end(bucket_count()))
throw torrent::input_error("Key not found.");
local_iterator itr = find_local_const(key);
return itr->second.object;
}
const torrent::Object&
object_storage::set_bool(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_bool_type)
throw torrent::input_error("Key not found or wrong type.");
local_iterator itr = find_local_mutable(key, flag_bool_type);
return itr->second.object = !!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.");
local_iterator itr = find_local_mutable(key, flag_value_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.");
local_iterator itr = find_local_mutable(key, flag_string_type);
return itr->second.object = object;
}
const torrent::Object&
object_storage::set_list(const torrent::raw_string& key, const torrent::Object::list_type& object) {
local_iterator itr = find_local(key);
if (itr == end(bucket_count()) || (itr->second.flags & mask_type) != flag_list_type)
throw torrent::input_error("Key not found or wrong type.");
local_iterator itr = find_local_mutable(key, flag_list_type);
return itr->second.object = torrent::Object::create_list_range(object.begin(), object.end());
}
void
object_storage::list_push_back(const torrent::raw_string& key, const torrent::Object& object) {
local_iterator itr = find_local_mutable(key, flag_list_type);
itr->second.object.as_list().push_back(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.");
local_iterator itr = find_local_mutable(key, flag_function_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()))
throw torrent::input_error("Key not found or wrong type.");
local_iterator itr = find_local_const(key);
switch (itr->second.flags & mask_type) {
case flag_function_type:
@@ -173,18 +191,13 @@ object_storage::call_function(const torrent::raw_string& key, target_type target
bool
object_storage::has_multi_key(const torrent::raw_string& key, const std::string& cmd_key) {
local_iterator itr = find_local(key);
return itr != end(0) && (itr->second.flags & mask_type) == flag_multi_type &&
itr->second.object.has_key(cmd_key);
local_iterator itr = find_local_const(key, flag_multi_type);
return itr->second.object.has_key(cmd_key);
}
void
object_storage::erase_multi_key(const torrent::raw_string& key, const std::string& cmd_key) {
local_iterator itr = find_local(key);
if (itr != end(0) && (itr->second.flags & mask_type) == flag_multi_type)
return;
local_iterator itr = find_local_mutable(key, flag_multi_type);
itr->second.object.erase_key(cmd_key);
@@ -209,10 +222,7 @@ object_storage::set_multi_key_obj(const torrent::raw_string& key, const std::str
if (!object.is_string() && !object.is_dict_key())
throw torrent::input_error("Object is wrong type.");
local_iterator itr = find_local(key);
if (itr == end(0) || (itr->second.flags & mask_type) != flag_multi_type)
throw torrent::input_error("Key not found or wrong type.");
local_iterator itr = find_local_mutable(key, flag_multi_type);
if (itr->second.flags & flag_rlookup) {
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
+11
View File
@@ -108,6 +108,8 @@ public:
static const size_t key_size = key_type::max_size;
local_iterator find_local(const torrent::raw_string& key);
local_iterator find_local_const(const torrent::raw_string& key, unsigned int type = 0);
local_iterator find_local_mutable(const torrent::raw_string& key, unsigned int type = 0);
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); }
@@ -116,6 +118,12 @@ public:
iterator insert(const torrent::raw_string& key, const torrent::Object& object, unsigned int flags);
iterator insert_str(const std::string& key, const torrent::Object& object, unsigned int flags);
bool has_flag(const torrent::raw_string& key, unsigned int flag);
bool has_flag_str(const std::string& key, unsigned int flag) { return has_flag(torrent::raw_string::from_string(key), flag); }
void enable_flag(const torrent::raw_string& key, unsigned int flag);
void enable_flag_str(const std::string& key, unsigned int flag) { enable_flag(torrent::raw_string::from_string(key), flag); }
// Access functions that throw on error.
const torrent::Object& get(const torrent::raw_string& key);
@@ -138,6 +146,9 @@ public:
const torrent::Object& set_c_str_list(const char* str, const torrent::Object::list_type& object) { return set_list(torrent::raw_string::from_c_str(str), object); }
const torrent::Object& set_str_list(const std::string& str, const torrent::Object::list_type& object) { return set_list(torrent::raw_string::from_string(str), object); }
void list_push_back(const torrent::raw_string& key, const torrent::Object& object);
void list_push_back_str(const std::string& str, const torrent::Object& object) { list_push_back(torrent::raw_string::from_string(str), object); }
// Functions callers:
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);