diff --git a/src/read_resume_data.cpp b/src/read_resume_data.cpp index da6d95189..813189bf6 100644 --- a/src/read_resume_data.cpp +++ b/src/read_resume_data.cpp @@ -337,8 +337,8 @@ namespace { bdecode_node const bitmask = e.dict_find_string("bitmask"); if (!bitmask || bitmask.string_length() == 0) continue; - bitfield& bf = ret.unfinished_pieces[piece]; - bf.assign(bitmask.string_ptr(), bitmask.string_length()); + ret.unfinished_pieces[piece].assign( + bitmask.string_ptr(), bitmask.string_length() * 8); } } diff --git a/src/write_resume_data.cpp b/src/write_resume_data.cpp index b27a3d066..59cc5c0e5 100644 --- a/src/write_resume_data.cpp +++ b/src/write_resume_data.cpp @@ -117,9 +117,7 @@ namespace libtorrent { // the unfinished piece's index piece_struct["piece"] = static_cast(p.first); - std::string& bitmask = piece_struct["bitmask"].string(); - for (auto const bit : p.second) - bitmask.push_back(bit ? '1' : '0'); + piece_struct["bitmask"] = std::string(p.second.data(), std::size_t(p.second.size() + 7) / 8); // push the struct onto the unfinished-piece list up.push_back(std::move(piece_struct)); } diff --git a/test/test_read_resume.cpp b/test/test_read_resume.cpp index b35392fc8..ff67aca84 100644 --- a/test/test_read_resume.cpp +++ b/test/test_read_resume.cpp @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/bencode.hpp" #include "libtorrent/add_torrent_params.hpp" #include "libtorrent/read_resume_data.hpp" +#include "libtorrent/write_resume_data.hpp" using namespace lt; @@ -220,3 +221,76 @@ TORRENT_TEST(read_resume_torrent) TEST_EQUAL(atp.ti->info_hash(), ti->info_hash()); TEST_EQUAL(atp.ti->name(), ti->name()); } + +namespace { + +void test_roundtrip(add_torrent_params const& input) +{ + auto b = write_resume_data_buf(input); + error_code ec; + auto output = read_resume_data(b, ec); + TEST_CHECK(write_resume_data_buf(output) == b); +} + +template +lt::typed_bitfield bits() +{ + lt::typed_bitfield b; + b.resize(19); + b.set_bit(T(2)); + b.set_bit(T(6)); + b.set_bit(T(12)); + return b; +} + +lt::bitfield bits() +{ + lt::bitfield b; + b.resize(19); + b.set_bit(2); + b.set_bit(6); + b.set_bit(12); + return b; +} + +template +std::vector vec() +{ + std::vector ret; + ret.resize(10); + ret[0] = T(1); + ret[1] = T(2); + ret[5] = T(3); + ret[7] = T(4); + return ret; +} +} + +TORRENT_TEST(round_trip_have_pieces) +{ + add_torrent_params atp; + atp.have_pieces = bits(); + test_roundtrip(atp); +} + +TORRENT_TEST(round_trip_verified_pieces) +{ + add_torrent_params atp; + atp.verified_pieces = bits(); + test_roundtrip(atp); +} + +TORRENT_TEST(round_trip_prios) +{ + add_torrent_params atp; + atp.piece_priorities = vec(); + test_roundtrip(atp); +} + +TORRENT_TEST(round_trip_unfinished) +{ + add_torrent_params atp; + atp.unfinished_pieces = std::map{{piece_index_t{42}, bits()}}; + test_roundtrip(atp); +} +