From effd1658d4c2f181eb9fb5949b9c983c991ec62a Mon Sep 17 00:00:00 2001 From: kannibalox Date: Sat, 14 Dec 2024 12:17:51 -0500 Subject: [PATCH] Create single-element maps for functions instead of using dict_keys --- src/rpc/parse.cc | 13 +++++++++---- src/rpc/parse_commands.cc | 32 ++++++++++++++++---------------- src/rpc/xmlrpc_c.cc | 26 -------------------------- src/rpc/xmlrpc_tinyxml2.cc | 20 -------------------- 4 files changed, 25 insertions(+), 66 deletions(-) diff --git a/src/rpc/parse.cc b/src/rpc/parse.cc index 63a6d046d..9ac885a05 100644 --- a/src/rpc/parse.cc +++ b/src/rpc/parse.cc @@ -194,10 +194,13 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (* if (depth > 3) throw torrent::input_error("Max 3 parantheses per object allowed."); - *dest = torrent::Object::create_dict_key(); + *dest = torrent::Object::create_map(); dest->set_flags(torrent::Object::flag_function << (depth - 1)); - first = parse_string(first + 1, last, &dest->as_dict_key(), &parse_is_delim_func); + std::string key; + torrent::Object val; + + first = parse_string(first + 1, last, &key, &parse_is_delim_func); first = parse_skip_wspace(first, last); if (first == last || !parse_is_delim_func(*first)) @@ -205,11 +208,13 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (* if (*first == ',') { // This will always create a list even for single argument functions... - dest->as_dict_obj() = torrent::Object::create_list(); - first = parse_list(first + 1, last, &dest->as_dict_obj(), &parse_is_delim_func); + val = torrent::Object::create_list(); + first = parse_list(first + 1, last, &val, &parse_is_delim_func); first = parse_skip_wspace(first, last); } + dest->as_map().insert({key, val}); + while (depth != 0 && first != last && *first == ')') { first++; depth--; diff --git a/src/rpc/parse_commands.cc b/src/rpc/parse_commands.cc index b3015868d..c524e7a5c 100644 --- a/src/rpc/parse_commands.cc +++ b/src/rpc/parse_commands.cc @@ -253,27 +253,27 @@ call_object(const torrent::Object& command, target_type target) { } case torrent::Object::TYPE_MAP: { + if (command.is_dict_key()) { + // This can/should be optimized... + torrent::Object tmp_command = command; + + // Unquote the root function object so 'parse_command_execute' + // doesn't end up calling it. + // + // TODO: Only call this if mask_function is set? + uint32_t flags = tmp_command.flags() & torrent::Object::mask_function; + tmp_command.unset_flags(torrent::Object::mask_function); + tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function); + + parse_command_execute(target, &tmp_command); + return commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target); + } + for (torrent::Object::map_const_iterator itr = command.as_map().begin(), last = command.as_map().end(); itr != last; itr++) call_object(itr->second, target); return torrent::Object(); } - case torrent::Object::TYPE_DICT_KEY: - { - // This can/should be optimized... - torrent::Object tmp_command = command; - - // Unquote the root function object so 'parse_command_execute' - // doesn't end up calling it. - // - // TODO: Only call this if mask_function is set? - uint32_t flags = tmp_command.flags() & torrent::Object::mask_function; - tmp_command.unset_flags(torrent::Object::mask_function); - tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function); - - parse_command_execute(target, &tmp_command); - return commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target); - } default: return torrent::Object(); } diff --git a/src/rpc/xmlrpc_c.cc b/src/rpc/xmlrpc_c.cc index af8bc1891..d41bf6342 100644 --- a/src/rpc/xmlrpc_c.cc +++ b/src/rpc/xmlrpc_c.cc @@ -351,32 +351,6 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) { return result; } - case torrent::Object::TYPE_DICT_KEY: - { - xmlrpc_value* result = xmlrpc_array_new(env); - - xmlrpc_value* key_item = object_to_xmlrpc(env, object.as_dict_key()); - xmlrpc_array_append_item(env, result, key_item); - xmlrpc_DECREF(key_item); - - if (object.as_dict_obj().is_list()) { - for (torrent::Object::list_const_iterator - itr = object.as_dict_obj().as_list().begin(), - last = object.as_dict_obj().as_list().end(); - itr != last; itr++) { - xmlrpc_value* item = object_to_xmlrpc(env, *itr); - xmlrpc_array_append_item(env, result, item); - xmlrpc_DECREF(item); - } - } else { - xmlrpc_value* arg_item = object_to_xmlrpc(env, object.as_dict_obj()); - xmlrpc_array_append_item(env, result, arg_item); - xmlrpc_DECREF(arg_item); - } - - return result; - } - default: return xmlrpc_int_new(env, 0); } diff --git a/src/rpc/xmlrpc_tinyxml2.cc b/src/rpc/xmlrpc_tinyxml2.cc index 9169e5ed6..3ab40706b 100644 --- a/src/rpc/xmlrpc_tinyxml2.cc +++ b/src/rpc/xmlrpc_tinyxml2.cc @@ -173,26 +173,6 @@ print_object_xml(const torrent::Object& obj, tinyxml2::XMLPrinter* printer) { } printer->CloseElement(true); break; - case torrent::Object::TYPE_DICT_KEY: - printer->OpenElement("array", true); - - printer->OpenElement("value", true); - print_object_xml(obj.as_dict_key(), printer); - printer->CloseElement(true); - - if (obj.as_dict_obj().is_list()) { - for (auto itr : obj.as_dict_obj().as_list()) { - printer->OpenElement("value", true); - print_object_xml(itr, printer); - printer->CloseElement(true); - } - } else { - printer->OpenElement("value", true); - print_object_xml(obj.as_dict_obj(), printer); - printer->CloseElement(true); - } - printer->CloseElement(true); - break; default: printer->OpenElement("i4", true); printer->PushText(0);