* Allow i8 and apache style 64bit integer support in XMLRPC. Use

"xmlrpc_dialect" command to change.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@929 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-07-05 13:10:13 +00:00
parent a492cadf00
commit 0c3038783e
3 changed files with 120 additions and 35 deletions
+85 -24
View File
@@ -49,10 +49,23 @@
namespace rpc {
// Ugly...
#ifdef XMLRPC_HAVE_I8
int XmlRpc::m_dialect = dialect_i8;
#else
int XmlRpc::m_dialect = dialect_generic;
#endif
XmlRpc::slot_find_download XmlRpc::m_slotFindDownload;
#ifdef HAVE_XMLRPC_C
xmlrpc_value* xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo);
xmlrpc_value* xmlrpc_call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo);
core::Download* xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value);
torrent::Object xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download);
torrent::Object
xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
switch (xmlrpc_value_type(value)) {
@@ -62,6 +75,14 @@ xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
return torrent::Object((int64_t)v);
#ifdef XMLRPC_HAVE_I8
case XMLRPC_TYPE_I8:
long long v2;
xmlrpc_read_i8(env, value, &v2);
return torrent::Object((int64_t)v2);
#endif
// case XMLRPC_TYPE_BOOL:
// case XMLRPC_TYPE_DOUBLE:
// case XMLRPC_TYPE_DATETIME:
@@ -119,7 +140,7 @@ xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
}
core::Download*
XmlRpc::xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
core::Download* download = NULL;
switch (xmlrpc_value_type(value)) {
@@ -131,7 +152,7 @@ XmlRpc::xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
return NULL;
if (std::strlen(valueString) != 40 ||
(download = m_slotFindDownload(valueString)) == NULL)
(download = XmlRpc::get_slot_find_download()(valueString)) == NULL)
xmlrpc_env_set_fault(env, XMLRPC_TYPE_ERROR, "Could not find info-hash.");
// Urgh, seriously?
@@ -147,7 +168,7 @@ XmlRpc::xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
// This should really be cleaned up and support for an array of
// downloads should be added.
torrent::Object
XmlRpc::xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download) {
xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download) {
switch (xmlrpc_value_type(value)) {
case XMLRPC_TYPE_STRING:
*download = xmlrpc_to_download(env, value);
@@ -223,33 +244,34 @@ XmlRpc::xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download*
xmlrpc_value*
object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
xmlrpc_value* result;
xmlrpc_int32 tmpInt;
switch (object.type()) {
case torrent::Object::TYPE_VALUE:
tmpInt = object.as_value();
return xmlrpc_build_value(env, "i", tmpInt);
#ifdef XMLRPC_HAVE_I8
if (XmlRpc::dialect() != XmlRpc::dialect_generic)
return xmlrpc_i8_new(env, object.as_value());
#else
return xmlrpc_int_new(env, object.as_value());
#endif
case torrent::Object::TYPE_STRING:
return xmlrpc_string_new(env, object.as_string().c_str());
case torrent::Object::TYPE_LIST:
result = xmlrpc_array_new(env);
xmlrpc_value* result = xmlrpc_array_new(env);
for (torrent::Object::list_type::const_iterator itr = object.as_list().begin(), last = object.as_list().end(); itr != last; itr++)
xmlrpc_array_append_item(env, result, object_to_xmlrpc(env, *itr));
return result;
default:
tmpInt = 0;
return xmlrpc_build_value(env, "i", tmpInt);
return xmlrpc_int_new(env, 0);
}
}
xmlrpc_value*
XmlRpc::call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
torrent::Object object = xmlrpc_to_object(env, args);
if (env->fault_occurred)
@@ -265,7 +287,7 @@ XmlRpc::call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo)
}
xmlrpc_value*
XmlRpc::call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
xmlrpc_call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
core::Download* download = NULL;
torrent::Object object = xmlrpc_to_object_d(env, args, &download);
@@ -281,15 +303,23 @@ XmlRpc::call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo
}
}
XmlRpc::XmlRpc() : m_env(new xmlrpc_env) {
xmlrpc_env_init(m_env);
m_registry = xmlrpc_registry_new(m_env);
XmlRpc::XmlRpc() :
m_env(new xmlrpc_env) {
// #ifdef XMLRPC_HAVE_I8
// m_dialect(dialect_i8) {
// #else
// m_dialect(dialect_generic) {
// #endif
xmlrpc_env_init((xmlrpc_env*)m_env);
m_registry = xmlrpc_registry_new((xmlrpc_env*)m_env);
}
XmlRpc::~XmlRpc() {
xmlrpc_registry_free(m_registry);
xmlrpc_env_clean(m_env);
delete m_env;
xmlrpc_registry_free((xmlrpc_registry*)m_registry);
xmlrpc_env_clean((xmlrpc_env*)m_env);
delete (xmlrpc_env*)m_env;
}
bool
@@ -297,7 +327,7 @@ XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
xmlrpc_env localEnv;
xmlrpc_env_init(&localEnv);
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, m_registry, NULL, inBuffer, length);
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
bool result = slotWrite((const char*)xmlrpc_mem_block_contents(memblock),
xmlrpc_mem_block_size(memblock));
@@ -312,8 +342,8 @@ XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool
xmlrpc_env localEnv;
xmlrpc_env_init(&localEnv);
xmlrpc_registry_add_method_w_doc(&localEnv, m_registry, NULL, name,
onDownload ? &XmlRpc::call_command_d : &XmlRpc::call_command,
xmlrpc_registry_add_method_w_doc(&localEnv, (xmlrpc_registry*)m_registry, NULL, name,
onDownload ? &xmlrpc_call_command_d : &xmlrpc_call_command,
const_cast<char*>(name), parm, doc);
if (localEnv.fault_occurred)
@@ -322,9 +352,40 @@ XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool
xmlrpc_env_clean(&localEnv);
}
void
XmlRpc::set_dialect(int dialect) {
xmlrpc_env localEnv;
xmlrpc_env_init(&localEnv);
switch (dialect) {
case dialect_generic:
break;
#ifdef XMLRPC_HAVE_I8
case dialect_i8:
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_i8);
break;
case dialect_apache:
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_apache);
break;
#endif
default:
xmlrpc_env_clean(&localEnv);
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
}
if (localEnv.fault_occurred)
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
xmlrpc_env_clean(&localEnv);
m_dialect = dialect;
}
#else
XmlRpc::XmlRpc() { throw torrent::resource_error("XMLRPC not supported."); }
XmlRpc::XmlRpc() : m_dialect(dialect_generic) { throw torrent::resource_error("XMLRPC not supported."); }
XmlRpc::~XmlRpc() {}
void XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool onDownload) {}