2009-01-24 06:29:23 +01:00
|
|
|
// Copyright Andrew Resch 2009. Use, modification and distribution is
|
2007-01-10 17:11:43 +01:00
|
|
|
// 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)
|
|
|
|
|
2016-04-08 04:45:23 +02:00
|
|
|
#include "boost_python.hpp"
|
2016-04-13 02:10:09 +02:00
|
|
|
#include "libtorrent/socket.hpp"
|
|
|
|
#include "libtorrent/address.hpp"
|
|
|
|
#include "libtorrent/error_code.hpp"
|
2016-12-23 22:57:10 +01:00
|
|
|
#include "libtorrent/session_stats.hpp" // for stats_metric
|
2016-11-10 23:08:32 +01:00
|
|
|
#include "libtorrent/time.hpp"
|
2016-12-22 16:42:33 +01:00
|
|
|
#include "libtorrent/units.hpp"
|
2016-12-29 17:54:28 +01:00
|
|
|
#include "libtorrent/sha1_hash.hpp"
|
2017-04-09 00:24:50 +02:00
|
|
|
#include "libtorrent/disk_interface.hpp" // for open_file_state
|
2016-04-13 02:10:09 +02:00
|
|
|
#include <vector>
|
2007-01-10 17:11:43 +01:00
|
|
|
|
2009-01-24 06:29:23 +01:00
|
|
|
using namespace boost::python;
|
2016-04-13 02:10:09 +02:00
|
|
|
namespace bp = boost::python;
|
|
|
|
namespace lt = libtorrent;
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
struct endpoint_to_tuple
|
|
|
|
{
|
|
|
|
static PyObject* convert(T const& ep)
|
|
|
|
{
|
|
|
|
return incref(bp::make_tuple(ep.address().to_string(), ep.port()).ptr());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
struct tuple_to_endpoint
|
|
|
|
{
|
|
|
|
tuple_to_endpoint()
|
|
|
|
{
|
|
|
|
converter::registry::push_back(
|
|
|
|
&convertible, &construct, type_id<T>()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void* convertible(PyObject* x)
|
|
|
|
{
|
2016-07-10 04:36:14 +02:00
|
|
|
if (!PyTuple_Check(x)) return nullptr;
|
|
|
|
if (PyTuple_Size(x) != 2) return nullptr;
|
2016-04-16 00:40:46 +02:00
|
|
|
extract<std::string> ip(object(borrowed(PyTuple_GetItem(x, 0))));
|
2016-07-10 04:36:14 +02:00
|
|
|
if (!ip.check()) return nullptr;
|
2016-04-16 00:40:46 +02:00
|
|
|
extract<int> port(object(borrowed(PyTuple_GetItem(x, 1))));
|
2016-07-10 04:36:14 +02:00
|
|
|
if (!port.check()) return nullptr;
|
2016-04-13 02:10:09 +02:00
|
|
|
lt::error_code ec;
|
2016-04-16 00:40:46 +02:00
|
|
|
lt::address::from_string(ip, ec);
|
2016-07-10 04:36:14 +02:00
|
|
|
if (ec) return nullptr;
|
2016-04-13 02:10:09 +02:00
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
|
|
|
|
{
|
|
|
|
void* storage = ((converter::rvalue_from_python_storage<T*>*)data)
|
|
|
|
->storage.bytes;
|
|
|
|
|
|
|
|
object o(borrowed(x));
|
|
|
|
new (storage) T(lt::address::from_string(
|
2016-04-16 00:40:46 +02:00
|
|
|
extract<std::string>(o[0])), extract<int>(o[1]));
|
2016-04-13 02:10:09 +02:00
|
|
|
data->convertible = storage;
|
|
|
|
}
|
|
|
|
};
|
2009-01-24 06:29:23 +01:00
|
|
|
|
|
|
|
template<class T1, class T2>
|
|
|
|
struct pair_to_tuple
|
|
|
|
{
|
|
|
|
static PyObject* convert(const std::pair<T1, T2>& p)
|
|
|
|
{
|
2016-04-13 02:10:09 +02:00
|
|
|
return incref(bp::make_tuple(p.first, p.second).ptr());
|
2009-01-24 06:29:23 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-11-14 02:52:56 +01:00
|
|
|
struct address_to_tuple
|
|
|
|
{
|
|
|
|
static PyObject* convert(libtorrent::address const& addr)
|
|
|
|
{
|
|
|
|
libtorrent::error_code ec;
|
|
|
|
return incref(bp::object(addr.to_string(ec)).ptr());
|
2009-01-24 06:29:23 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class T1, class T2>
|
|
|
|
struct tuple_to_pair
|
|
|
|
{
|
|
|
|
tuple_to_pair()
|
|
|
|
{
|
|
|
|
converter::registry::push_back(
|
2016-10-25 23:27:48 +02:00
|
|
|
&convertible, &construct, type_id<std::pair<T1, T2>>()
|
2009-01-24 06:29:23 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void* convertible(PyObject* x)
|
|
|
|
{
|
2016-07-10 04:36:14 +02:00
|
|
|
return (PyTuple_Check(x) && PyTuple_Size(x) == 2) ? x: nullptr;
|
2009-01-24 06:29:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
|
|
|
|
{
|
|
|
|
void* storage = ((converter::rvalue_from_python_storage<
|
2016-10-25 23:27:48 +02:00
|
|
|
std::pair<T1, T2>>*)data)->storage.bytes;
|
2009-01-24 06:29:23 +01:00
|
|
|
|
|
|
|
object o(borrowed(x));
|
|
|
|
std::pair<T1, T2> p;
|
|
|
|
p.first = extract<T1>(o[0]);
|
|
|
|
p.second = extract<T2>(o[1]);
|
|
|
|
new (storage) std::pair<T1, T2>(p);
|
|
|
|
data->convertible = storage;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-01-24 15:26:11 +01:00
|
|
|
template<class T1, class T2>
|
|
|
|
struct dict_to_map
|
|
|
|
{
|
|
|
|
dict_to_map()
|
|
|
|
{
|
|
|
|
converter::registry::push_back(
|
|
|
|
&convertible, &construct, type_id<std::map<T1, T2>>()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
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<T1, T2>>*)data)->storage.bytes;
|
|
|
|
|
|
|
|
dict o(borrowed(x));
|
|
|
|
std::map<T1, T2> m;
|
|
|
|
|
|
|
|
list iterkeys = (list)o.keys();
|
|
|
|
int const len = int(boost::python::len(iterkeys));
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
object key = iterkeys[i];
|
|
|
|
m[extract<T1>(key)] = extract<T2>(o[key]);
|
|
|
|
}
|
|
|
|
new (storage) std::map<T1, T2>(m);
|
|
|
|
data->convertible = storage;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-04-13 02:10:09 +02:00
|
|
|
template<class T>
|
|
|
|
struct vector_to_list
|
|
|
|
{
|
|
|
|
static PyObject* convert(const std::vector<T>& v)
|
|
|
|
{
|
|
|
|
list l;
|
2016-05-21 22:23:15 +02:00
|
|
|
for (int i = 0; i < int(v.size()); ++i)
|
2016-04-13 02:10:09 +02:00
|
|
|
{
|
|
|
|
l.append(v[i]);
|
|
|
|
}
|
|
|
|
return incref(l.ptr());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
struct list_to_vector
|
|
|
|
{
|
|
|
|
list_to_vector()
|
|
|
|
{
|
|
|
|
converter::registry::push_back(
|
2016-10-25 23:27:48 +02:00
|
|
|
&convertible, &construct, type_id<std::vector<T>>()
|
2016-04-13 02:10:09 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void* convertible(PyObject* x)
|
|
|
|
{
|
2016-07-10 04:36:14 +02:00
|
|
|
return PyList_Check(x) ? x: nullptr;
|
2016-04-13 02:10:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
|
|
|
|
{
|
|
|
|
void* storage = ((converter::rvalue_from_python_storage<
|
2016-10-25 23:27:48 +02:00
|
|
|
std::vector<T>>*)data)->storage.bytes;
|
2016-04-13 02:10:09 +02:00
|
|
|
|
|
|
|
std::vector<T> p;
|
2016-06-19 01:24:27 +02:00
|
|
|
int const size = int(PyList_Size(x));
|
2016-04-13 02:10:09 +02:00
|
|
|
p.reserve(size);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
object o(borrowed(PyList_GetItem(x, i)));
|
|
|
|
p.push_back(extract<T>(o));
|
|
|
|
}
|
|
|
|
std::vector<T>* ptr = new (storage) std::vector<T>();
|
|
|
|
ptr->swap(p);
|
|
|
|
data->convertible = storage;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-12-22 16:42:33 +01:00
|
|
|
template<class T>
|
|
|
|
struct from_strong_typedef
|
|
|
|
{
|
|
|
|
using underlying_type = typename T::underlying_type;
|
|
|
|
|
|
|
|
static PyObject* convert(const T& v)
|
|
|
|
{
|
|
|
|
object o(static_cast<underlying_type>(v));
|
|
|
|
return incref(o.ptr());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct to_strong_typedef
|
|
|
|
{
|
|
|
|
using underlying_type = typename T::underlying_type;
|
|
|
|
|
|
|
|
to_strong_typedef()
|
|
|
|
{
|
|
|
|
converter::registry::push_back(
|
|
|
|
&convertible, &construct, type_id<T>()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
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<T>*)data)->storage.bytes;
|
|
|
|
new (storage) T(extract<underlying_type>(object(borrowed(x))));
|
|
|
|
data->convertible = storage;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-01-24 06:29:23 +01:00
|
|
|
void bind_converters()
|
|
|
|
{
|
2016-04-13 02:10:09 +02:00
|
|
|
// C++ -> python conversions
|
2016-10-25 23:27:48 +02:00
|
|
|
to_python_converter<std::pair<int, int>, pair_to_tuple<int, int>>();
|
2016-12-22 16:42:33 +01:00
|
|
|
to_python_converter<std::pair<lt::piece_index_t, int>, pair_to_tuple<lt::piece_index_t, int>>();
|
2016-10-25 23:27:48 +02:00
|
|
|
to_python_converter<lt::tcp::endpoint, endpoint_to_tuple<lt::tcp::endpoint>>();
|
|
|
|
to_python_converter<lt::udp::endpoint, endpoint_to_tuple<lt::udp::endpoint>>();
|
2016-11-14 02:52:56 +01:00
|
|
|
to_python_converter<lt::address, address_to_tuple>();
|
2017-01-24 15:26:11 +01:00
|
|
|
to_python_converter<std::pair<std::string, int>, pair_to_tuple<std::string, int>>();
|
2016-11-14 03:54:09 +01:00
|
|
|
|
2016-12-29 17:54:28 +01:00
|
|
|
to_python_converter<std::vector<lt::stats_metric>, vector_to_list<lt::stats_metric>>();
|
2017-04-09 00:24:50 +02:00
|
|
|
to_python_converter<std::vector<lt::open_file_state>, vector_to_list<lt::open_file_state>>();
|
2016-12-29 17:54:28 +01:00
|
|
|
to_python_converter<std::vector<lt::sha1_hash>, vector_to_list<lt::sha1_hash>>();
|
2016-10-25 23:27:48 +02:00
|
|
|
to_python_converter<std::vector<std::string>, vector_to_list<std::string>>();
|
|
|
|
to_python_converter<std::vector<int>, vector_to_list<int>>();
|
|
|
|
to_python_converter<std::vector<std::uint8_t>, vector_to_list<std::uint8_t>>();
|
|
|
|
to_python_converter<std::vector<lt::tcp::endpoint>, vector_to_list<lt::tcp::endpoint>>();
|
|
|
|
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<lt::udp::endpoint>>();
|
|
|
|
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::pair<std::string, int>>>();
|
2016-04-13 02:10:09 +02:00
|
|
|
|
2016-12-22 16:42:33 +01:00
|
|
|
to_python_converter<lt::piece_index_t, from_strong_typedef<lt::piece_index_t>>();
|
|
|
|
to_python_converter<lt::file_index_t, from_strong_typedef<lt::file_index_t>>();
|
|
|
|
|
2016-04-13 02:10:09 +02:00
|
|
|
// python -> C++ conversions
|
2009-01-24 06:29:23 +01:00
|
|
|
tuple_to_pair<int, int>();
|
2016-04-13 02:10:09 +02:00
|
|
|
tuple_to_pair<std::string, int>();
|
|
|
|
tuple_to_endpoint<lt::tcp::endpoint>();
|
|
|
|
tuple_to_endpoint<lt::udp::endpoint>();
|
2016-12-22 16:42:33 +01:00
|
|
|
tuple_to_pair<lt::piece_index_t, int>();
|
2017-01-24 15:26:11 +01:00
|
|
|
dict_to_map<lt::file_index_t, std::string>();
|
2016-04-13 02:10:09 +02:00
|
|
|
list_to_vector<int>();
|
2016-06-18 20:01:38 +02:00
|
|
|
list_to_vector<std::uint8_t>();
|
2016-04-13 02:10:09 +02:00
|
|
|
list_to_vector<std::string>();
|
|
|
|
list_to_vector<lt::tcp::endpoint>();
|
|
|
|
list_to_vector<lt::udp::endpoint>();
|
2016-10-25 23:27:48 +02:00
|
|
|
list_to_vector<std::pair<std::string, int>>();
|
2016-12-22 16:42:33 +01:00
|
|
|
|
|
|
|
to_strong_typedef<lt::piece_index_t>();
|
|
|
|
to_strong_typedef<lt::file_index_t>();
|
2009-01-24 06:29:23 +01:00
|
|
|
}
|