diff --git a/include/libtorrent/part_file.hpp b/include/libtorrent/part_file.hpp index 0f179ce5f..cf08f4698 100644 --- a/include/libtorrent/part_file.hpp +++ b/include/libtorrent/part_file.hpp @@ -43,6 +43,9 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { + struct slot_index_tag_t {}; + using slot_index_t = aux::strong_typedef; + struct TORRENT_EXTRA_EXPORT part_file { // create a part file at 'path', that can hold 'num_pieces' pieces. @@ -74,7 +77,7 @@ namespace libtorrent std::string m_name; // allocate a slot and return the slot index - int allocate_slot(piece_index_t piece); + slot_index_t allocate_slot(piece_index_t piece); // this mutex must be held while accessing the data // structure. Not while reading or writing from the file though! @@ -83,10 +86,10 @@ namespace libtorrent // this is a list of unallocated slots in the part file // within the m_num_allocated range - std::vector m_free_slots; + std::vector m_free_slots; // this is the number of slots allocated - int m_num_allocated; + slot_index_t m_num_allocated; // the max number of pieces in the torrent this part file is // backing @@ -106,7 +109,7 @@ namespace libtorrent bool m_dirty_metadata; // maps a piece index to the part-file slot it is stored in - std::unordered_map m_piece_map; + std::unordered_map m_piece_map; // this is the file handle to the part file file m_file; diff --git a/simulation/test_tracker.cpp b/simulation/test_tracker.cpp index 5d34694ed..3a4a039cd 100644 --- a/simulation/test_tracker.cpp +++ b/simulation/test_tracker.cpp @@ -701,7 +701,7 @@ std::shared_ptr make_torrent(bool priv) ct.add_tracker("http://tracker.com:8080/announce"); - for (int i = 0; i < ct.num_pieces(); ++i) + for (piece_index_t i(0); i < piece_index_t(ct.num_pieces()); ++i) ct.set_hash(i, sha1_hash(nullptr)); ct.set_priv(priv); diff --git a/simulation/test_web_seed.cpp b/simulation/test_web_seed.cpp index 24774e894..7c80fd373 100644 --- a/simulation/test_web_seed.cpp +++ b/simulation/test_web_seed.cpp @@ -57,10 +57,10 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false , pad_files ? create_torrent::optimize_alignment : 0); std::vector piece(piece_size); - int const num = t.num_pieces(); + piece_index_t const num = fs.end_piece(); if (pad_files) { - for (int i = 0; i < num; ++i) + for (piece_index_t i(0); i < num; ++i) { std::vector files = fs.map_block(i, 0, fs.piece_size(i)); int k = 0; @@ -92,7 +92,7 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false // calculate the hash for all pieces sha1_hash ph = hasher(&piece[0], int(piece.size())).final(); - for (int i = 0; i < num; ++i) + for (piece_index_t i(0); i < num; ++i) t.set_hash(i, ph); } @@ -100,7 +100,7 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false if ((fs.total_size() % piece_size) > 0) { piece.resize(fs.total_size() % piece_size); - t.set_hash(num-1, hasher(&piece[0], int(piece.size())).final()); + t.set_hash(prev(num), hasher(&piece[0], int(piece.size())).final()); } std::vector tmp; @@ -239,7 +239,7 @@ TORRENT_TEST(multi_file) TEST_CHECK(expected[1]); } -std::string generate_content(lt::file_storage const& fs, int file +std::string generate_content(lt::file_storage const& fs, file_index_t file , std::int64_t offset, std::int64_t len) { std::string ret; @@ -252,9 +252,9 @@ std::string generate_content(lt::file_storage const& fs, int file } void serve_content_for(sim::http_server& http, std::string const& path - , lt::file_storage const& fs, int const file) + , lt::file_storage const& fs, file_index_t const file) { - http.register_content(path, fs.file_size(file) + http.register_content(path, fs.file_size(file_index_t(file)) , [&fs,file](std::int64_t offset, std::int64_t len) { return generate_content(fs, file, offset, len); }); } @@ -294,8 +294,8 @@ TORRENT_TEST(unaligned_file_redirect) // server for serving the content sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3")); sim::http_server http2(web_server2, 4444); - serve_content_for(http2, "/bla/file1", fs, 0); - serve_content_for(http2, "/bar/file2", fs, 1); + serve_content_for(http2, "/bla/file1", fs, file_index_t(0)); + serve_content_for(http2, "/bar/file2", fs, file_index_t(1)); sim.run(); } @@ -343,12 +343,12 @@ TORRENT_TEST(multi_file_redirect_pad_files) // server for file 1 sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3")); sim::http_server http2(web_server2, 4444); - serve_content_for(http2, "/bla/file1", fs, 0); + serve_content_for(http2, "/bla/file1", fs, file_index_t(0)); // server for file 2 sim::asio::io_service web_server3(sim, address_v4::from_string("4.4.4.4")); sim::http_server http3(web_server3, 9999); - serve_content_for(http3, "/bar/file2", fs, 2); + serve_content_for(http3, "/bar/file2", fs, file_index_t(2)); sim.run(); } @@ -391,12 +391,12 @@ TORRENT_TEST(multi_file_redirect) // server for file 1 sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3")); sim::http_server http2(web_server2, 4444); - serve_content_for(http2, "/bla/file1", fs, 0); + serve_content_for(http2, "/bla/file1", fs, file_index_t(0)); // server for file 2 sim::asio::io_service web_server3(sim, address_v4::from_string("4.4.4.4")); sim::http_server http3(web_server3, 9999); - serve_content_for(http3, "/bar/file2", fs, 1); + serve_content_for(http3, "/bar/file2", fs, file_index_t(1)); sim.run(); } @@ -438,12 +438,12 @@ TORRENT_TEST(multi_file_unaligned_redirect) // server for file 1 sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3")); sim::http_server http2(web_server2, 4444); - serve_content_for(http2, "/bla/file1", fs, 0); + serve_content_for(http2, "/bla/file1", fs, file_index_t(0)); // server for file 2 sim::asio::io_service web_server3(sim, address_v4::from_string("4.4.4.4")); sim::http_server http3(web_server3, 9999); - serve_content_for(http3, "/bar/file2", fs, 1); + serve_content_for(http3, "/bar/file2", fs, file_index_t(1)); sim.run(); } diff --git a/src/part_file.cpp b/src/part_file.cpp index d7da2d971..80cefbae8 100644 --- a/src/part_file.cpp +++ b/src/part_file.cpp @@ -64,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/part_file.hpp" #include "libtorrent/io.hpp" #include "libtorrent/assert.hpp" +#include "libtorrent/aux_/vector.hpp" namespace { @@ -113,28 +114,27 @@ namespace libtorrent // this is used to determine which slots are free, and how many // slots are allocated - std::vector free_slots; + aux::vector free_slots; free_slots.resize(num_pieces, true); for (piece_index_t i = piece_index_t(0); i < piece_index_t(num_pieces); ++i) { - std::uint32_t const uslot = read_uint32(ptr); - if (uslot == 0xffffffff) continue; - int const slot = int(uslot); + slot_index_t const slot(read_int32(ptr)); + if (static_cast(slot) < 0) continue; // invalid part-file - TORRENT_ASSERT(slot < num_pieces); - if (slot >= num_pieces) continue; + TORRENT_ASSERT(slot < slot_index_t(num_pieces)); + if (slot >= slot_index_t(num_pieces)) continue; if (slot >= m_num_allocated) - m_num_allocated = slot + 1; + m_num_allocated = next(slot); free_slots[slot] = false; m_piece_map[i] = slot; } // now, populate the free_list with the "holes" - for (int i = 0; i < m_num_allocated; ++i) + for (slot_index_t i(0); i < m_num_allocated; ++i) { if (free_slots[i]) m_free_slots.push_back(i); } @@ -149,12 +149,12 @@ namespace libtorrent flush_metadata_impl(ec); } - int part_file::allocate_slot(piece_index_t const piece) + slot_index_t part_file::allocate_slot(piece_index_t const piece) { // the mutex is assumed to be held here, since this is a private function TORRENT_ASSERT(m_piece_map.find(piece) == m_piece_map.end()); - int slot = -1; + slot_index_t slot(-1); if (!m_free_slots.empty()) { slot = m_free_slots.front(); @@ -180,16 +180,13 @@ namespace libtorrent open_file(file::read_write, ec); if (ec) return -1; - int slot = -1; auto const i = m_piece_map.find(piece); - if (i == m_piece_map.end()) - slot = allocate_slot(piece); - else - slot = i->second; + slot_index_t const slot = (i == m_piece_map.end()) + ? allocate_slot(piece) : i->second; l.unlock(); - std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(slot) * m_piece_size; + std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(static_cast(slot)) * m_piece_size; return int(m_file.writev(slot_offset + offset, bufs, ec)); } @@ -207,14 +204,13 @@ namespace libtorrent return -1; } - int slot = i->second; - + slot_index_t const slot = i->second; open_file(file::read_write, ec); if (ec) return -1; l.unlock(); - std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(slot) * m_piece_size; + std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(static_cast(slot)) * m_piece_size; return int(m_file.readv(slot_offset + offset, bufs, ec)); } @@ -316,14 +312,14 @@ namespace libtorrent int const block_to_copy = int(std::min(m_piece_size - piece_offset, size)); if (i != m_piece_map.end()) { - int const slot = i->second; + slot_index_t const slot = i->second; open_file(file::read_only, ec); if (ec) return; if (!buf) buf.reset(new char[m_piece_size]); std::int64_t const slot_offset = std::int64_t(m_header_size) - + std::int64_t(slot) * m_piece_size; + + std::int64_t(static_cast(slot)) * m_piece_size; // don't hold the lock during disk I/O l.unlock(); @@ -407,10 +403,9 @@ namespace libtorrent for (piece_index_t piece(0); piece < piece_index_t(m_max_pieces); ++piece) { auto const i = m_piece_map.find(piece); - int const slot = i == m_piece_map.end() - ? 0xffffffff - : i->second; - write_uint32(slot, ptr); + slot_index_t const slot(i == m_piece_map.end() + ? slot_index_t(-1) : i->second); + write_int32(static_cast(slot), ptr); } std::memset(ptr, 0, m_header_size - (ptr - reinterpret_cast(header.get())));