make create_torrent flags type-safe

This commit is contained in:
arvidn 2017-08-03 03:02:03 -07:00 committed by Arvid Norberg
parent cb114a80e1
commit 5bf28e37b8
7 changed files with 93 additions and 71 deletions

View File

@ -18,6 +18,7 @@
#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 <vector>
using namespace boost::python;
@ -314,6 +315,7 @@ void bind_converters()
to_python_converter<lt::session_flags_t, from_bitfield_flag<lt::session_flags_t>>();
to_python_converter<lt::remove_flags_t, from_bitfield_flag<lt::remove_flags_t>>();
to_python_converter<lt::file_flags_t, from_bitfield_flag<lt::file_flags_t>>();
to_python_converter<lt::create_flags_t, from_bitfield_flag<lt::create_flags_t>>();
// work-around types
to_python_converter<lt::aux::noexcept_movable<lt::address>, address_to_tuple<
@ -372,4 +374,5 @@ void bind_converters()
to_bitfield_flag<lt::session_flags_t>();
to_bitfield_flag<lt::remove_flags_t>();
to_bitfield_flag<lt::file_flags_t>();
to_bitfield_flag<lt::create_flags_t>();
}

View File

@ -109,7 +109,7 @@ namespace
#endif // TORRENT_NO_DEPRECATE
void add_files_callback(file_storage& fs, std::string const& file
, boost::python::object cb, std::uint32_t flags)
, boost::python::object cb, create_flags_t const flags)
{
add_files(fs, file, [&](std::string const& i) { return cb(i); }, flags);
}
@ -126,6 +126,7 @@ namespace
}
struct dummy13 {};
struct dummy14 {};
}
void bind_create_torrent()
@ -140,7 +141,7 @@ void bind_create_torrent()
#ifndef BOOST_NO_EXCEPTIONS
void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
#endif
void (*add_files0)(file_storage&, std::string const&, std::uint32_t) = add_files;
void (*add_files0)(file_storage&, std::string const&, create_flags_t) = add_files;
std::string const& (file_storage::*file_storage_symlink)(file_index_t) const = &file_storage::symlink;
sha1_hash (file_storage::*file_storage_hash)(file_index_t) const = &file_storage::hash;
@ -202,11 +203,12 @@ void bind_create_torrent()
s.attr("flag_symlink") = file_storage::flag_symlink;
}
class_<create_torrent>("create_torrent", no_init)
{
scope s = class_<create_torrent>("create_torrent", no_init)
.def(init<file_storage&>())
.def(init<torrent_info const&>(arg("ti")))
.def(init<file_storage&, int, int, int>((arg("storage"), arg("piece_size") = 0
, arg("pad_file_limit") = -1, arg("flags") = int(lt::create_torrent::optimize_alignment))))
.def(init<file_storage&, int, int, create_flags_t>((arg("storage"), arg("piece_size") = 0
, arg("pad_file_limit") = -1, arg("flags") = lt::create_torrent::optimize_alignment)))
.def("generate", &create_torrent::generate)
@ -227,15 +229,22 @@ void bind_create_torrent()
.def("set_root_cert", &create_torrent::set_root_cert, (arg("pem")))
;
enum_<create_torrent::flags_t>("create_torrent_flags_t")
s.attr("optimize_alignment") = create_torrent::optimize_alignment;
s.attr("merkle") = create_torrent::merkle;
s.attr("modification_time") = create_torrent::modification_time;
s.attr("symlinks") = create_torrent::symlinks;
}
{
scope s = class_<dummy14>("create_torrent_flags_t");
#ifndef TORRENT_NO_DEPRECATE
.value("optimize", create_torrent::optimize)
s.attr("optimize") = create_torrent::optimize;
#endif
.value("optimize_alignment", create_torrent::optimize_alignment)
.value("merkle", create_torrent::merkle)
.value("modification_time", create_torrent::modification_time)
.value("symlinks", create_torrent::symlinks)
;
s.attr("optimize_alignment") = create_torrent::optimize_alignment;
s.attr("merkle") = create_torrent::merkle;
s.attr("modification_time") = create_torrent::modification_time;
s.attr("symlinks") = create_torrent::symlinks;
}
def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
def("add_files", add_files_callback, (arg("fs"), arg("path")

View File

@ -182,7 +182,7 @@ int main(int argc, char* argv[])
std::vector<sha1_hash> similar;
int pad_file_limit = -1;
int piece_size = 0;
int flags = 0;
create_flags_t flags = {};
std::string root_cert;
std::string outfile;

View File

@ -92,56 +92,56 @@ namespace libtorrent {
class torrent_info;
// hidden
struct create_flags_tag;
using create_flags_t = flags::bitfield_flag<std::uint32_t, create_flags_tag>;
// This class holds state for creating a torrent. After having added
// all information to it, call create_torrent::generate() to generate
// the torrent. The entry that's returned can then be bencoded into a
// .torrent file using bencode().
struct TORRENT_EXPORT create_torrent
{
// flags for create_torrent::create_torrent().
enum flags_t
{
// This will insert pad files to align the files to piece boundaries, for
// optimized disk-I/O. This will minimize the number of bytes of pad-
// files, to keep the impact down for clients that don't support
// them.
optimize_alignment = 1,
// This will insert pad files to align the files to piece boundaries, for
// optimized disk-I/O. This will minimize the number of bytes of pad-
// files, to keep the impact down for clients that don't support
// them.
static constexpr create_flags_t optimize_alignment = 0_bit;
#ifndef TORRENT_NO_DEPRECATE
// same as optimize_alignment, for backwards compatibility
optimize TORRENT_DEPRECATED_ENUM = 1,
// same as optimize_alignment, for backwards compatibility
static constexpr create_flags_t TORRENT_DEPRECATED_MEMBER optimize = 0_bit;
#endif
// This will create a merkle hash tree torrent. A merkle torrent cannot
// be opened in clients that don't specifically support merkle torrents.
// The benefit is that the resulting torrent file will be much smaller and
// not grow with more pieces. When this option is specified, it is
// recommended to have a fairly small piece size, say 64 kiB.
// When creating merkle torrents, the full hash tree is also generated
// and should be saved off separately. It is accessed through the
// create_torrent::merkle_tree() function.
merkle = 2,
// This will create a merkle hash tree torrent. A merkle torrent cannot
// be opened in clients that don't specifically support merkle torrents.
// The benefit is that the resulting torrent file will be much smaller and
// not grow with more pieces. When this option is specified, it is
// recommended to have a fairly small piece size, say 64 kiB.
// When creating merkle torrents, the full hash tree is also generated
// and should be saved off separately. It is accessed through the
// create_torrent::merkle_tree() function.
static constexpr create_flags_t merkle = 1_bit;
// This will include the file modification time as part of the torrent.
// This is not enabled by default, as it might cause problems when you
// create a torrent from separate files with the same content, hoping to
// yield the same info-hash. If the files have different modification times,
// with this option enabled, you would get different info-hashes for the
// files.
modification_time = 4,
// This will include the file modification time as part of the torrent.
// This is not enabled by default, as it might cause problems when you
// create a torrent from separate files with the same content, hoping to
// yield the same info-hash. If the files have different modification times,
// with this option enabled, you would get different info-hashes for the
// files.
static constexpr create_flags_t modification_time = 2_bit;
// If this flag is set, files that are symlinks get a symlink attribute
// set on them and their data will not be included in the torrent. This
// is useful if you need to reconstruct a file hierarchy which contains
// symlinks.
symlinks = 8,
// If this flag is set, files that are symlinks get a symlink attribute
// set on them and their data will not be included in the torrent. This
// is useful if you need to reconstruct a file hierarchy which contains
// symlinks.
static constexpr create_flags_t symlinks = 3_bit;
// to create a torrent that can be updated via a *mutable torrent*
// (see `BEP 38`_). This also needs to be enabled for torrents that update
// another torrent.
//
// .. _`BEP 38`: http://www.bittorrent.org/beps/bep_0038.html
mutable_torrent_support = 16
};
// to create a torrent that can be updated via a *mutable torrent*
// (see `BEP 38`_). This also needs to be enabled for torrents that update
// another torrent.
//
// .. _`BEP 38`: http://www.bittorrent.org/beps/bep_0038.html
static constexpr create_flags_t mutable_torrent_support = 4_bit;
// The ``piece_size`` is the size of each piece in bytes. It must
// be a multiple of 16 kiB. If a piece size of 0 is specified, a
@ -167,7 +167,7 @@ namespace libtorrent {
// eligible files are aligned to. The default is -1, which means the
// piece size of the torrent.
explicit create_torrent(file_storage& fs, int piece_size = 0
, int pad_file_limit = -1, int flags = optimize_alignment
, int pad_file_limit = -1, create_flags_t flags = optimize_alignment
, int alignment = -1);
explicit create_torrent(torrent_info const& ti);
@ -388,9 +388,9 @@ namespace detail {
// The ``flags`` argument should be the same as the flags passed to the `create_torrent`_
// constructor.
TORRENT_EXPORT void add_files(file_storage& fs, std::string const& file
, std::function<bool(std::string)> p, std::uint32_t flags = 0);
, std::function<bool(std::string)> p, create_flags_t flags = {});
TORRENT_EXPORT void add_files(file_storage& fs, std::string const& file
, std::uint32_t flags = 0);
, create_flags_t flags = {});
// This function will assume that the files added to the torrent file exists at path
// ``p``, read those files and hash the content and set the hashes in the ``create_torrent``
@ -430,11 +430,11 @@ namespace detail {
TORRENT_DEPRECATED_EXPORT
void add_files(file_storage& fs, std::wstring const& wfile
, std::function<bool(std::string)> p, std::uint32_t flags = 0);
, std::function<bool(std::string)> p, create_flags_t flags = {});
TORRENT_DEPRECATED_EXPORT
void add_files(file_storage& fs, std::wstring const& wfile
, std::uint32_t flags = 0);
, create_flags_t flags = {});
TORRENT_DEPRECATED_EXPORT
void set_piece_hashes(create_torrent& t, std::wstring const& p

View File

@ -58,7 +58,7 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false
{
lt::create_torrent t(fs, piece_size
, pad_files ? piece_size : -1
, pad_files ? create_torrent::optimize_alignment : 0);
, pad_files ? create_torrent::optimize_alignment : create_flags_t{});
std::vector<char> piece;
piece.reserve(fs.piece_length());

View File

@ -50,6 +50,16 @@ POSSIBILITY OF SUCH DAMAGE.
using namespace std::placeholders;
namespace libtorrent {
constexpr create_flags_t create_torrent::optimize_alignment;
#ifndef TORRENT_NO_DEPRECATE
constexpr create_flags_t create_torrent::optimize;
#endif
constexpr create_flags_t create_torrent::merkle;
constexpr create_flags_t create_torrent::modification_time;
constexpr create_flags_t create_torrent::symlinks;
constexpr create_flags_t create_torrent::mutable_torrent_support;
namespace {
bool default_pred(std::string const&) { return true; }
@ -105,7 +115,7 @@ namespace {
void add_files_impl(file_storage& fs, std::string const& p
, std::string const& l, std::function<bool(std::string)> pred
, std::uint32_t const flags)
, create_flags_t const flags)
{
std::string f = combine_path(p, l);
if (!pred(f)) return;
@ -195,7 +205,7 @@ namespace {
#ifndef TORRENT_NO_DEPRECATE
void add_files(file_storage& fs, std::wstring const& wfile
, std::function<bool(std::string)> p, std::uint32_t flags)
, std::function<bool(std::string)> p, create_flags_t const flags)
{
std::string utf8 = wchar_utf8(wfile);
add_files_impl(fs, parent_path(complete(utf8))
@ -203,7 +213,7 @@ namespace {
}
void add_files(file_storage& fs
, std::wstring const& wfile, std::uint32_t flags)
, std::wstring const& wfile, create_flags_t const flags)
{
std::string utf8 = wchar_utf8(wfile);
add_files_impl(fs, parent_path(complete(utf8))
@ -226,12 +236,12 @@ namespace {
#endif // TORRENT_NO_DEPRECATE
void add_files(file_storage& fs, std::string const& file
, std::function<bool(std::string)> p, std::uint32_t flags)
, std::function<bool(std::string)> p, create_flags_t const flags)
{
add_files_impl(fs, parent_path(complete(file)), filename(file), p, flags);
}
void add_files(file_storage& fs, std::string const& file, std::uint32_t flags)
void add_files(file_storage& fs, std::string const& file, create_flags_t const flags)
{
add_files_impl(fs, parent_path(complete(file)), filename(file)
, default_pred, flags);
@ -300,14 +310,14 @@ namespace {
create_torrent::~create_torrent() = default;
create_torrent::create_torrent(file_storage& fs, int piece_size
, int pad_file_limit, int flags, int alignment)
, int pad_file_limit, create_flags_t const flags, int alignment)
: m_files(fs)
, m_creation_date(time(nullptr))
, m_multifile(fs.num_files() > 1)
, m_private(false)
, m_merkle_torrent((flags & merkle) != 0)
, m_include_mtime((flags & modification_time) != 0)
, m_include_symlinks((flags & symlinks) != 0)
, m_merkle_torrent(bool(flags & create_torrent::merkle))
, m_include_mtime(bool(flags & create_torrent::modification_time))
, m_include_symlinks(bool(flags & create_torrent::symlinks))
{
// return instead of crash in release mode
if (fs.num_files() == 0 || fs.total_size() == 0) return;
@ -353,7 +363,7 @@ namespace {
#endif
m_files.set_piece_length(piece_size);
if (flags & (optimize_alignment | mutable_torrent_support))
m_files.optimize(pad_file_limit, alignment, (flags & mutable_torrent_support) != 0);
m_files.optimize(pad_file_limit, alignment, bool(flags & mutable_torrent_support));
m_files.set_num_pieces(static_cast<int>(
(m_files.total_size() + m_files.piece_length() - 1) / m_files.piece_length()));

View File

@ -130,7 +130,7 @@ std::shared_ptr<torrent_info> setup_torrent_info(file_storage& fs
fs.add_file(combine_path("temp_storage", combine_path("folder2", "test3.tmp")), 0);
fs.add_file(combine_path("temp_storage", combine_path("_folder3", "test4.tmp")), 0);
fs.add_file(combine_path("temp_storage", combine_path("_folder3", combine_path("subfolder", "test5.tmp"))), 8);
lt::create_torrent t(fs, 4, -1, 0);
lt::create_torrent t(fs, 4, -1, {});
char buf_[4] = {0, 0, 0, 0};
sha1_hash h = hasher(buf_).final();
@ -442,7 +442,7 @@ void test_check_files(std::string const& test_path
std::vector<char> piece0 = new_piece(piece_size);
std::vector<char> piece2 = new_piece(piece_size);
lt::create_torrent t(fs, piece_size, -1, 0);
lt::create_torrent t(fs, piece_size, -1, {});
t.set_hash(piece_index_t(0), hasher(piece0).final());
t.set_hash(piece_index_t(1), sha1_hash(nullptr));
t.set_hash(piece_index_t(2), sha1_hash(nullptr));
@ -539,7 +539,7 @@ void run_test(bool unbuffered)
// | | | | |
// | piece 0 | piece 1 | piece 2 | piece 3 |
lt::create_torrent t(fs, piece_size, -1, 0);
lt::create_torrent t(fs, piece_size, -1, {});
TEST_CHECK(t.num_pieces() == 4);
t.set_hash(piece_index_t(0), hasher(piece0).final());
t.set_hash(piece_index_t(1), hasher(piece1).final());
@ -584,7 +584,7 @@ void run_test(bool unbuffered)
error_code ec;
file_storage fs;
fs.add_file(combine_path("temp_storage", "test1.tmp"), 3 * piece_size);
lt::create_torrent t(fs, piece_size, -1, 0);
lt::create_torrent t(fs, piece_size, -1, {});
TEST_CHECK(fs.file_path(file_index_t(0)) == combine_path("temp_storage", "test1.tmp"));
t.set_hash(piece_index_t(0), hasher(piece0).final());
t.set_hash(piece_index_t(1), hasher(piece1).final());