// Copyright Andrew Resch 2009. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include "boost_python.hpp" #include "libtorrent/socket.hpp" #include "libtorrent/address.hpp" #include "libtorrent/error_code.hpp" #include "libtorrent/session_stats.hpp" // for stats_metric #include "libtorrent/time.hpp" #include "libtorrent/torrent_flags.hpp" #include "libtorrent/units.hpp" #include "libtorrent/sha1_hash.hpp" #include "libtorrent/disk_interface.hpp" // for open_file_state #include "libtorrent/aux_/noexcept_movable.hpp" #include "libtorrent/peer_info.hpp" #include "libtorrent/alert_types.hpp" // for picker_flags_t #include "libtorrent/session_types.hpp" // for save_state_flags_t #include "libtorrent/file_storage.hpp" // for file_flags_t #include "libtorrent/alert.hpp" #include "libtorrent/create_torrent.hpp" // for create_flags_t #include "libtorrent/portmap.hpp" // for port_mapping_t #include "libtorrent/peer_class.hpp" #include "libtorrent/pex_flags.hpp" #include "libtorrent/string_view.hpp" #include #include using namespace boost::python; namespace bp = boost::python; template struct endpoint_to_tuple { static PyObject* convert(T const& ep) { return incref(bp::make_tuple(ep.address().to_string(), ep.port()).ptr()); } }; template struct tuple_to_endpoint { tuple_to_endpoint() { converter::registry::push_back( &convertible, &construct, type_id() ); } static void* convertible(PyObject* x) { if (!PyTuple_Check(x)) return nullptr; if (PyTuple_Size(x) != 2) return nullptr; extract ip(object(borrowed(PyTuple_GetItem(x, 0)))); if (!ip.check()) return nullptr; extract port(object(borrowed(PyTuple_GetItem(x, 1)))); if (!port.check()) return nullptr; lt::error_code ec; lt::address::from_string(ip, ec); if (ec) return nullptr; return x; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage*)data) ->storage.bytes; object o(borrowed(x)); data->convertible = new (storage) T(lt::address::from_string( extract(o[0])), extract(o[1])); } }; template struct pair_to_tuple { static PyObject* convert(const std::pair& p) { return incref(bp::make_tuple(p.first, p.second).ptr()); } }; template struct address_to_tuple { static PyObject* convert(Addr const& addr) { lt::error_code ec; return incref(bp::object(addr.to_string(ec)).ptr()); } }; template struct tuple_to_pair { tuple_to_pair() { converter::registry::push_back( &convertible, &construct, type_id>() ); } static void* convertible(PyObject* x) { return (PyTuple_Check(x) && PyTuple_Size(x) == 2) ? x: nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage< std::pair>*)data)->storage.bytes; object o(borrowed(x)); std::pair p; p.first = extract(o[0]); p.second = extract(o[1]); data->convertible = new (storage) std::pair(p); } }; struct from_string_view { static PyObject* convert(lt::string_view v) { str ret(v.data(), v.size()); return incref(ret.ptr()); } }; struct to_string_view { to_string_view() { converter::registry::push_back( &convertible, &construct, type_id() ); } static void* convertible(PyObject* x) { return PyUnicode_Check(x) ? x: nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage< lt::string_view>*)data)->storage.bytes; data->convertible = new (storage) lt::string_view(PyUnicode_AS_DATA(x), PyUnicode_GET_DATA_SIZE(x)); } }; template struct map_to_dict { static PyObject* convert(Map const& m) { dict ret; for (auto const& e : m) ret[e.first] = e.second; return incref(ret.ptr()); } }; template> struct dict_to_map { dict_to_map() { converter::registry::push_back( &convertible, &construct, type_id>() ); } static void* convertible(PyObject* x) { return PyDict_Check(x) ? x: nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage< std::map>*)data)->storage.bytes; dict o(borrowed(x)); Map m; stl_input_iterator i(o.keys()), end; for (; i != end; ++i) { T1 const& key = *i; m[key] = extract(o[key]); } data->convertible = new (storage) std::map(m); } }; template struct vector_to_list { static PyObject* convert(T const& v) { list l; for (int i = 0; i < int(v.size()); ++i) { l.append(v[i]); } return incref(l.ptr()); } }; template struct list_to_vector { list_to_vector() { converter::registry::push_back( &convertible, &construct, type_id() ); } static void* convertible(PyObject* x) { return PyList_Check(x) ? x: nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage< T>*)data)->storage.bytes; T p; int const size = int(PyList_Size(x)); p.reserve(size); for (int i = 0; i < size; ++i) { object o(borrowed(PyList_GetItem(x, i))); p.push_back(extract(o)); } data->convertible = new (storage) T(std::move(p)); } }; template struct list_to_bitfield { list_to_bitfield() { converter::registry::push_back( &convertible, &construct, type_id() ); } static void* convertible(PyObject* x) { return PyList_Check(x) ? x : nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage< T>*)data)->storage.bytes; T p; int const size = int(PyList_Size(x)); p.resize(size); for (int i = 0; i < size; ++i) { object o(borrowed(PyList_GetItem(x, i))); if (extract(o)) p.set_bit(IndexType{i}); else p.clear_bit(IndexType{i}); } data->convertible = new (storage) T(std::move(p)); } }; template struct bitfield_to_list { static PyObject* convert(T const& v) { list ret; for (auto const& i : v) ret.append(i); return incref(ret.ptr()); } }; template struct from_strong_typedef { using underlying_type = typename T::underlying_type; static PyObject* convert(const T& v) { object o(static_cast(v)); return incref(o.ptr()); } }; template struct to_strong_typedef { using underlying_type = typename T::underlying_type; to_strong_typedef() { converter::registry::push_back( &convertible, &construct, type_id() ); } static void* convertible(PyObject* x) { return PyNumber_Check(x) ? x : nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage*)data)->storage.bytes; data->convertible = new (storage) T(extract(object(borrowed(x)))); } }; template struct from_bitfield_flag { using underlying_type = typename T::underlying_type; static PyObject* convert(T const v) { // this is because python uses "long int" to represent integral values // internally, it cannot hold large unsigned values auto const val = static_cast(v) & static_cast(std::numeric_limits::max()); object o(val); return incref(o.ptr()); } }; template struct to_bitfield_flag { using underlying_type = typename T::underlying_type; to_bitfield_flag() { converter::registry::push_back( &convertible, &construct, type_id() ); } static void* convertible(PyObject* x) { return PyNumber_Check(x) ? x : nullptr; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) { void* storage = ((converter::rvalue_from_python_storage*)data)->storage.bytes; data->convertible = new (storage) T(extract(object(borrowed(x)))); } }; void bind_converters() { // C++ -> python conversions to_python_converter, pair_to_tuple>(); to_python_converter, pair_to_tuple>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter, pair_to_tuple>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter, vector_to_list>>(); to_python_converter>, vector_to_list>>>(); to_python_converter, bitfield_to_list>>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter>(); to_python_converter(); // work-around types to_python_converter, address_to_tuple< lt::aux::noexcept_movable>>(); to_python_converter, endpoint_to_tuple< lt::aux::noexcept_movable>>(); to_python_converter, endpoint_to_tuple< lt::aux::noexcept_movable>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>, vector_to_list>>>(); to_python_converter>>, vector_to_list>>>>(); to_python_converter>, map_to_dict>>>(); to_python_converter>, map_to_dict>>>(); to_python_converter, map_to_dict>>(); #if TORRENT_ABI_VERSION == 1 to_python_converter>, vector_to_list>>>(); list_to_vector>>(); #endif // python -> C++ conversions tuple_to_pair(); tuple_to_pair(); tuple_to_endpoint(); tuple_to_endpoint(); tuple_to_pair(); dict_to_map(); list_to_vector>(); list_to_vector>(); list_to_vector>(); list_to_vector>(); list_to_vector>(); list_to_vector>>(); // work-around types list_to_vector>>(); list_to_vector>>(); list_to_vector>>(); list_to_vector>>(); list_to_vector>>(); list_to_vector>>>(); dict_to_map>>(); dict_to_map>>(); // bitfield types list_to_bitfield, lt::piece_index_t>(); list_to_bitfield(); bitfield_to_list>(); bitfield_to_list(); to_strong_typedef(); to_strong_typedef(); to_strong_typedef(); to_strong_typedef(); to_strong_typedef(); to_strong_typedef(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); to_bitfield_flag(); }