1 // rTorrent - BitTorrent client 2 // Copyright (C) 2005-2011, Jari Sundell 3 // 4 // This program is free software; you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation; either version 2 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 // 18 // In addition, as a special exception, the copyright holders give 19 // permission to link the code of portions of this program with the 20 // OpenSSL library under certain conditions as described in each 21 // individual source file, and distribute linked combinations 22 // including the two. 23 // 24 // You must obey the GNU General Public License in all respects for 25 // all of the code used other than OpenSSL. If you modify file(s) 26 // with this exception, you may extend this exception to your version 27 // of the file(s), but you are not obligated to do so. If you do not 28 // wish to do so, delete this exception statement from your version. 29 // If you delete this exception statement from all source files in the 30 // program, then also delete it here. 31 // 32 // Contact: Jari Sundell <jaris@ifi.uio.no> 33 // 34 // Skomakerveien 33 35 // 3185 Skoppum, NORWAY 36 37 #ifndef RTORRENT_UTILS_COMMAND_HELPERS_H 38 #define RTORRENT_UTILS_COMMAND_HELPERS_H 39 40 #include "rpc/command.h" 41 #include "rpc/parse_commands.h" 42 #include "rpc/object_storage.h" 43 44 void initialize_commands(); 45 46 // 47 // New std::function based command_base helper functions: 48 // 49 50 #define CMD2_A_FUNCTION(key, function, slot, parm, doc) \ 51 rpc::commands.insert_slot<rpc::command_base_is_type<rpc::function>::type>(key, slot, &rpc::function, \ 52 rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, NULL, NULL); 53 54 #define CMD2_A_FUNCTION_PRIVATE(key, function, slot, parm, doc) \ 55 rpc::commands.insert_slot<rpc::command_base_is_type<rpc::function>::type>(key, slot, &rpc::function, \ 56 rpc::CommandMap::flag_dont_delete, NULL, NULL); 57 58 #define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, slot, "i:", "") 59 60 #define CMD2_ANY_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call<rpc::target_type>, slot, "i:", "") 61 #define CMD2_ANY_VOID(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, object_convert_void(slot), "i:", "") 62 #define CMD2_ANY_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, object_convert_void(slot), "i:", "") 63 #define CMD2_ANY_L(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, slot, "A:", "") 64 65 #define CMD2_ANY_VALUE(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<rpc::target_type>, slot, "i:i", "") 66 #define CMD2_ANY_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<rpc::target_type>, object_convert_void(slot), "i:i", "") 67 #define CMD2_ANY_VALUE_KB(key, slot) CMD2_A_FUNCTION(key, command_base_call_value_kb<rpc::target_type>, object_convert_void(slot), "i:i", "") 68 69 #define CMD2_ANY_STRING(key, slot) CMD2_A_FUNCTION(key, command_base_call_string<rpc::target_type>, slot, "i:s", "") 70 #define CMD2_ANY_STRING_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_string<rpc::target_type>, object_convert_void(slot), "i:s", "") 71 72 #define CMD2_ANY_LIST(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, slot, "i:", "") 73 74 #define CMD2_DL(key, slot) CMD2_A_FUNCTION(key, command_base_call<core::Download*>, slot, "i:", "") 75 #define CMD2_DL_V(key, slot) CMD2_A_FUNCTION(key, command_base_call<core::Download*>, object_convert_void(slot), "i:", "") 76 #define CMD2_DL_VALUE(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<core::Download*>, slot, "i:", "") 77 #define CMD2_DL_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<core::Download*>, object_convert_void(slot), "i:", "") 78 #define CMD2_DL_STRING(key, slot) CMD2_A_FUNCTION(key, command_base_call_string<core::Download*>, slot, "i:", "") 79 #define CMD2_DL_STRING_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_string<core::Download*>, object_convert_void(slot), "i:", "") 80 #define CMD2_DL_LIST(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<core::Download*>, slot, "i:", "") 81 82 #define CMD2_DL_VALUE_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call_value<core::Download*>, slot, "i:", "") 83 #define CMD2_DL_STRING_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call_string<core::Download*>, slot, "i:", "") 84 85 #define CMD2_FILE(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::File*>, slot, "i:", "") 86 #define CMD2_FILE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::File*>, object_convert_void(slot), "i:", "") 87 #define CMD2_FILE_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<torrent::File*>, object_convert_void(slot), "i:i", "") 88 89 #define CMD2_FILEITR(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::FileListIterator*>, slot, "i:", "") 90 91 #define CMD2_PEER(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::Peer*>, slot, "i:", "") 92 #define CMD2_PEER_V(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::Peer*>, object_convert_void(slot), "i:", "") 93 #define CMD2_PEER_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<torrent::Peer*>, object_convert_void(slot), "i:i", "") 94 95 #define CMD2_TRACKER(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::Tracker*>, slot, "i:", "") 96 #define CMD2_TRACKER_V(key, slot) CMD2_A_FUNCTION(key, command_base_call<torrent::Tracker*>, object_convert_void(slot), "i:", "") 97 #define CMD2_TRACKER_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<torrent::Tracker*>, object_convert_void(slot), "i:i", "") 98 99 #define CMD2_VAR_BOOL(key, value) \ 100 control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_bool_type); \ 101 CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ 102 torrent::raw_string::from_c_str(key))); \ 103 CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_bool, control->object_storage(), \ 104 torrent::raw_string::from_c_str(key), std::placeholders::_2)); 105 106 #define CMD2_VAR_VALUE(key, value) \ 107 control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_value_type); \ 108 CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ 109 torrent::raw_string::from_c_str(key))); \ 110 CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_value, control->object_storage(), \ 111 torrent::raw_string::from_c_str(key), std::placeholders::_2)); 112 113 #define CMD2_VAR_STRING(key, value) \ 114 control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \ 115 CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ 116 torrent::raw_string::from_c_str(key))); \ 117 CMD2_ANY_STRING(key ".set", std::bind(&rpc::object_storage::set_string, control->object_storage(), \ 118 torrent::raw_string::from_c_str(key), std::placeholders::_2)); 119 120 121 #define CMD2_VAR_C_STRING(key, value) \ 122 control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \ 123 CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ 124 torrent::raw_string::from_c_str(key))); 125 126 #define CMD2_VAR_LIST(key) \ 127 control->object_storage()->insert_c_str(key, torrent::Object::create_list(), rpc::object_storage::flag_list_type); \ 128 CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \ 129 torrent::raw_string::from_c_str(key))); \ 130 CMD2_ANY_LIST(key ".set", std::bind(&rpc::object_storage::set_list, control->object_storage(), \ 131 torrent::raw_string::from_c_str(key), std::placeholders::_2)); \ 132 CMD2_ANY_VOID(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \ 133 torrent::raw_string::from_c_str(key), std::placeholders::_2)); 134 135 #define CMD2_FUNC_SINGLE(key, cmds) \ 136 CMD2_ANY(key, std::bind(&rpc::command_function_call_object, torrent::Object(torrent::raw_string::from_c_str(cmds)), \ 137 std::placeholders::_1, std::placeholders::_2)); 138 139 #define CMD2_REDIRECT(from_key, to_key) \ 140 rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_dont_delete); 141 #define CMD2_REDIRECT_GENERIC(from_key, to_key) \ 142 rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_dont_delete); 143 #define CMD2_REDIRECT_GENERIC_NO_EXPORT(from_key, to_key) \ 144 rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_dont_delete); 145 #define CMD2_REDIRECT_FILE(from_key, to_key) \ 146 rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_file_target | rpc::CommandMap::flag_dont_delete); 147 #define CMD2_REDIRECT_TRACKER(from_key, to_key) \ 148 rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_tracker_target | rpc::CommandMap::flag_dont_delete); 149 150 #define CMD2_REDIRECT_GENERIC_STR(from_key, to_key) \ 151 rpc::commands.create_redirect(create_new_key(from_key), create_new_key(to_key), \ 152 rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_delete_key); 153 154 #define CMD2_REDIRECT_GENERIC_STR_NO_EXPORT(from_key, to_key) \ 155 rpc::commands.create_redirect(create_new_key(from_key), create_new_key(to_key), \ 156 rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_delete_key); 157 158 // 159 // Conversion of return types: 160 // 161 162 template <typename Functor, typename Result> 163 struct object_convert_type; 164 165 template <typename Functor> 166 struct object_convert_type<Functor, void> { 167 168 template <typename Signature> struct result { 169 typedef torrent::Object type; 170 }; 171 172 object_convert_type(Functor s) : m_slot(s) {} 173 174 torrent::Object operator () () { m_slot(); return torrent::Object(); } 175 template <typename Arg1> 176 torrent::Object operator () (Arg1& arg1) { m_slot(arg1); return torrent::Object(); } 177 template <typename Arg1, typename Arg2> 178 torrent::Object operator () (const Arg1& arg1) { m_slot(arg1); return torrent::Object(); } 179 template <typename Arg1, typename Arg2> 180 torrent::Object operator () (Arg1& arg1, Arg2& arg2) { m_slot(arg1, arg2); return torrent::Object(); } 181 template <typename Arg1, typename Arg2> 182 torrent::Object operator () (const Arg1& arg1, const Arg2& arg2) { m_slot(arg1, arg2); return torrent::Object(); } 183 184 Functor m_slot; 185 }; 186 187 template <typename T> 188 object_convert_type<T, void> 189 object_convert_void(T f) { return f; } 190 191 // 192 // Key creation: 193 // 194 195 template <int postfix_size> 196 inline const char* 197 create_new_key(const std::string& key, const char postfix[postfix_size]) { 198 char *buffer = new char[key.size() + std::max(postfix_size, 1)]; 199 std::memcpy(buffer, key.c_str(), key.size() + 1); 200 std::memcpy(buffer + key.size(), postfix, postfix_size); 201 return buffer; 202 } 203 204 inline const char* 205 create_new_key(const std::string& key) { 206 char *buffer = new char[key.size() + 1]; 207 std::memcpy(buffer, key.c_str(), key.size() + 1); 208 return buffer; 209 } 210 211 #endif 212