// 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 using namespace boost::python; namespace bp = boost::python; namespace lt = libtorrent; 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)); new (storage) T(lt::address::from_string( extract(o[0])), extract(o[1])); data->convertible = storage; } }; template struct pair_to_tuple { static PyObject* convert(const std::pair& p) { return incref(bp::make_tuple(p.first, p.second).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]); new (storage) std::pair(p); data->convertible = storage; } }; template struct vector_to_list { static PyObject* convert(const std::vector& 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< std::vector >*)data)->storage.bytes; std::vector 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)); } std::vector* ptr = new (storage) std::vector(); ptr->swap(p); data->convertible = storage; } }; 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, 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 > >(); // python -> C++ conversions tuple_to_pair(); tuple_to_pair(); tuple_to_endpoint(); tuple_to_endpoint(); list_to_vector(); list_to_vector(); list_to_vector(); list_to_vector(); list_to_vector(); list_to_vector >(); }