From b8e77444d576ee0dcb8adaad62f97d8f6d3696d2 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 29 Mar 2017 16:10:32 -0400 Subject: [PATCH] use span for read_resume_data() (#1867) use span for read_resume_data() --- bindings/python/src/session.cpp | 2 +- examples/bt-get2.cpp | 2 +- examples/client_test.cpp | 6 +++--- include/libtorrent/bdecode.hpp | 11 +++++++++-- include/libtorrent/read_resume_data.hpp | 5 +++-- src/bdecode.cpp | 23 ++++++++++++++++++----- src/read_resume_data.cpp | 5 ++--- src/session_handle.cpp | 2 +- test/test_priority.cpp | 2 +- test/test_read_resume.cpp | 10 +++++----- test/test_resume.cpp | 8 ++++---- test/test_storage.cpp | 4 ++-- 12 files changed, 50 insertions(+), 30 deletions(-) diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index c768467d0..005732aff 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -559,7 +559,7 @@ namespace add_torrent_params read_resume_data_wrapper(bytes const& b) { error_code ec; - add_torrent_params p = read_resume_data(&b.arr[0], int(b.arr.size()), ec); + add_torrent_params p = read_resume_data(b.arr, ec); #ifndef BOOST_NO_EXCEPTIONS if (ec) throw system_error(ec); #endif diff --git a/examples/bt-get2.cpp b/examples/bt-get2.cpp index b24f164d3..527a24b8b 100644 --- a/examples/bt-get2.cpp +++ b/examples/bt-get2.cpp @@ -87,7 +87,7 @@ int main(int argc, char const* argv[]) , std::istream_iterator()}; lt::error_code ec; - lt::add_torrent_params atp = lt::read_resume_data(&buf[0], int(buf.size()), ec); + lt::add_torrent_params atp = lt::read_resume_data(buf, ec); if (ec) { std::cerr << "failed to read resume data: " << ec.message() << std::endl; return 1; diff --git a/examples/client_test.cpp b/examples/client_test.cpp index f9ddda326..feae1db06 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -555,7 +555,7 @@ void add_magnet(lt::session& ses, lt::string_view uri) load_file(resume_file(p.info_hash), resume_data, ec); if (!ec) { - p = lt::read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = lt::read_resume_data(resume_data, ec); if (ec) std::printf(" failed to load resume data: %s\n", ec.message().c_str()); parse_magnet_uri(uri.to_string(), p, ec); } @@ -599,7 +599,7 @@ bool add_torrent(libtorrent::session& ses, std::string torrent) load_file(resume_file(ti->info_hash()), resume_data, ec); if (!ec) { - p = lt::read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = lt::read_resume_data(resume_data, ec); if (ec) std::printf(" failed to load resume data: %s\n", ec.message().c_str()); } ec.clear(); @@ -1286,7 +1286,7 @@ MAGNETURL is a magnet link , file.c_str(), ec.message().c_str()); continue; } - add_torrent_params p = lt::read_resume_data(&resume_data[0], int(resume_data.size()), ec); + add_torrent_params p = lt::read_resume_data(resume_data, ec); if (ec) { std::printf(" failed to parse resume data \"%s\": %s\n" diff --git a/include/libtorrent/bdecode.hpp b/include/libtorrent/bdecode.hpp index f62738829..9a5f220ee 100644 --- a/include/libtorrent/bdecode.hpp +++ b/include/libtorrent/bdecode.hpp @@ -247,12 +247,14 @@ struct bdecode_token // There are 5 different types of nodes, see type_t. struct TORRENT_EXPORT bdecode_node { - // TODO: 3 make this take span for buffer, and make it return a - // bdecode_node + // TODO: 3 deprecate this overload TORRENT_EXPORT friend int bdecode(char const* start, char const* end, bdecode_node& ret , error_code& ec, int* error_pos, int depth_limit , int token_limit); + TORRENT_EXPORT friend bdecode_node bdecode(span buffer + , error_code& ec, int* error_pos, int depth_limit, int token_limit); + // creates a default constructed node, it will have the type ``none_t``. bdecode_node(); @@ -260,6 +262,8 @@ struct TORRENT_EXPORT bdecode_node // underlying buffer remains the same. bdecode_node(bdecode_node const&); bdecode_node& operator=(bdecode_node const&); + bdecode_node(bdecode_node&&); + bdecode_node& operator=(bdecode_node&&); // the types of bdecoded nodes enum type_t @@ -421,6 +425,9 @@ TORRENT_EXPORT std::string print_entry(bdecode_node const& e TORRENT_EXPORT int bdecode(char const* start, char const* end, bdecode_node& ret , error_code& ec, int* error_pos = nullptr, int depth_limit = 100 , int token_limit = 1000000); +TORRENT_EXPORT bdecode_node bdecode(span buffer + , error_code& ec, int* error_pos = nullptr, int depth_limit = 100 + , int token_limit = 1000000); } diff --git a/include/libtorrent/read_resume_data.hpp b/include/libtorrent/read_resume_data.hpp index d32c76e88..a711686bf 100644 --- a/include/libtorrent/read_resume_data.hpp +++ b/include/libtorrent/read_resume_data.hpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/error_code.hpp" #include "libtorrent/export.hpp" +#include "libtorrent/span.hpp" namespace libtorrent { @@ -51,8 +52,8 @@ namespace libtorrent // data but before adding the torrent. TORRENT_EXPORT add_torrent_params read_resume_data(bdecode_node const& rd , error_code& ec); - TORRENT_EXPORT add_torrent_params read_resume_data(char const* buffer - , int size, error_code& ec); + TORRENT_EXPORT add_torrent_params read_resume_data(span buffer + , error_code& ec); } #endif diff --git a/src/bdecode.cpp b/src/bdecode.cpp index 209bb39dc..065fcaf90 100644 --- a/src/bdecode.cpp +++ b/src/bdecode.cpp @@ -243,6 +243,9 @@ namespace libtorrent return *this; } + bdecode_node::bdecode_node(bdecode_node&&) = default; + bdecode_node& bdecode_node::operator=(bdecode_node&&) = default; + bdecode_node::bdecode_node(bdecode_token const* tokens, char const* buf , int len, int idx) : m_root_tokens(tokens) @@ -647,14 +650,21 @@ namespace libtorrent int bdecode(char const* start, char const* end, bdecode_node& ret , error_code& ec, int* error_pos, int const depth_limit, int token_limit) { - ec.clear(); - ret.clear(); + ret = bdecode({start, static_cast(end - start)}, ec, error_pos, depth_limit, token_limit); + return ec ? -1 : 0; + } - if (end - start > bdecode_token::max_offset) + bdecode_node bdecode(span buffer + , error_code& ec, int* error_pos, int depth_limit, int token_limit) + { + bdecode_node ret; + ec.clear(); + + if (buffer.size() > bdecode_token::max_offset) { if (error_pos) *error_pos = 0; ec = bdecode_errors::limit_exceeded; - return -1; + return ret; } // this is the stack of bdecode_token indices, into m_tokens. @@ -662,6 +672,9 @@ namespace libtorrent int sp = 0; TORRENT_ALLOCA(stack, stack_frame, depth_limit); + // TODO: 2 attempt to simplify this implementation by embracing the span + char const* start = buffer.data(); + char const* end = start + buffer.size(); char const* const orig_start = start; if (start == end) @@ -853,7 +866,7 @@ done: ret.m_buffer_size = int(start - orig_start); ret.m_root_tokens = ret.m_tokens.data(); - return ec ? -1 : 0; + return ret; } namespace { diff --git a/src/read_resume_data.cpp b/src/read_resume_data.cpp index b0410adbf..2c9ce65c2 100644 --- a/src/read_resume_data.cpp +++ b/src/read_resume_data.cpp @@ -332,10 +332,9 @@ namespace libtorrent return ret; } - add_torrent_params read_resume_data(char const* buffer, int size, error_code& ec) + add_torrent_params read_resume_data(span buffer, error_code& ec) { - bdecode_node rd; - bdecode(buffer, buffer + size, rd, ec); + bdecode_node rd = bdecode(buffer, ec); if (ec) return add_torrent_params(); return read_resume_data(rd, ec); diff --git a/src/session_handle.cpp b/src/session_handle.cpp index 668cac3eb..4fe1e269b 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -200,7 +200,7 @@ namespace libtorrent error_code ec; add_torrent_params resume_data - = read_resume_data(&atp.resume_data[0], int(atp.resume_data.size()), ec); + = read_resume_data(atp.resume_data, ec); resume_data.internal_resume_data_error = ec; if (ec) return; diff --git a/test/test_priority.cpp b/test/test_priority.cpp index 3f37e5a95..9ddeca29c 100644 --- a/test/test_priority.cpp +++ b/test/test_priority.cpp @@ -295,7 +295,7 @@ done: #endif { error_code ec; - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = read_resume_data(resume_data, ec); TEST_CHECK(!ec); } p.flags &= ~add_torrent_params::flag_paused; diff --git a/test/test_read_resume.cpp b/test/test_read_resume.cpp index 919b380e1..841955557 100644 --- a/test/test_read_resume.cpp +++ b/test/test_read_resume.cpp @@ -77,7 +77,7 @@ TORRENT_TEST(read_resume) bencode(std::back_inserter(resume_data), rd); error_code ec; - add_torrent_params atp = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + add_torrent_params atp = read_resume_data(resume_data, ec); TEST_CHECK(!ec); @@ -123,7 +123,7 @@ TORRENT_TEST(read_resume_missing_info_hash) bencode(std::back_inserter(resume_data), rd); error_code ec; - add_torrent_params atp = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + add_torrent_params atp = read_resume_data(resume_data, ec); TEST_EQUAL(ec, error_code(errors::missing_info_hash)); } @@ -139,7 +139,7 @@ TORRENT_TEST(read_resume_missing_file_format) bencode(std::back_inserter(resume_data), rd); error_code ec; - add_torrent_params atp = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + add_torrent_params atp = read_resume_data(resume_data, ec); TEST_EQUAL(ec, error_code(errors::invalid_file_tag)); } @@ -161,7 +161,7 @@ TORRENT_TEST(read_resume_mismatching_torrent) // the info-hash field does not match the torrent in the "info" field, so it // will be ignored error_code ec; - add_torrent_params atp = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + add_torrent_params atp = read_resume_data(resume_data, ec); TEST_CHECK(!ec); TEST_CHECK(!atp.ti); } @@ -207,7 +207,7 @@ TORRENT_TEST(read_resume_torrent) // the info-hash field does not match the torrent in the "info" field, so it // will be ignored error_code ec; - add_torrent_params atp = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + add_torrent_params atp = read_resume_data(resume_data, ec); TEST_CHECK(!ec); TEST_CHECK(atp.ti); diff --git a/test/test_resume.cpp b/test/test_resume.cpp index 28d109fa9..8203accfe 100644 --- a/test/test_resume.cpp +++ b/test/test_resume.cpp @@ -157,7 +157,7 @@ torrent_handle test_resume_flags(lt::session& ses, int flags #endif { error_code ec; - p = read_resume_data(&rd[0], int(rd.size()), ec); + p = read_resume_data(rd, ec); TEST_CHECK(!ec); } @@ -241,7 +241,7 @@ void test_piece_priorities(bool test_deprecated = false) #endif { error_code ec; - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = read_resume_data(resume_data, ec); TEST_CHECK(!ec); p.ti = ti; p.save_path = "."; @@ -735,7 +735,7 @@ void test_zero_file_prio(bool test_deprecated = false) #endif { error_code ec; - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = read_resume_data(resume_data, ec); TEST_CHECK(!ec); p.ti = ti; p.save_path = "."; @@ -820,7 +820,7 @@ void test_seed_mode(bool const file_prio, bool const pieces_have, bool const pie #endif { error_code ec; - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = read_resume_data(resume_data, ec); TEST_CHECK(!ec); p.ti = ti; p.save_path = "."; diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 54d774bd1..898790766 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -710,7 +710,7 @@ void test_fastresume(bool const test_deprecated) else #endif { - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = read_resume_data(resume_data, ec); TEST_CHECK(!ec); } @@ -880,7 +880,7 @@ void test_rename_file_fastresume(bool test_deprecated) else #endif { - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = read_resume_data(resume_data, ec); TEST_CHECK(!ec); } p.ti = std::make_shared(std::cref(*t));