From 5530793c75421096ee832880096de4997fe55085 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 2 Jun 2018 19:29:40 +0200 Subject: [PATCH] improve the API for iterating over all files and pieces, with the new strong index types. --- CMakeLists.txt | 1 + examples/connection_tester.cpp | 2 +- examples/dump_torrent.cpp | 2 +- include/libtorrent/Makefile.am | 2 + include/libtorrent/bitfield.hpp | 22 ++++++--- include/libtorrent/file_storage.hpp | 44 ++++++++---------- include/libtorrent/index_range.hpp | 72 +++++++++++++++++++++++++++++ include/libtorrent/torrent_info.hpp | 5 ++ src/bitfield.cpp | 8 ++-- src/create_torrent.cpp | 4 +- src/file_storage.cpp | 38 +++++++++++++++ src/resolve_links.cpp | 4 +- src/storage.cpp | 2 +- src/storage_utils.cpp | 26 ++++++----- src/torrent.cpp | 14 +++--- src/torrent_info.cpp | 6 +-- src/web_peer_connection.cpp | 2 +- test/make_torrent.cpp | 2 +- test/setup_transfer.cpp | 4 +- test/test_bitfield.cpp | 12 +++++ test/test_file_progress.cpp | 4 +- test/test_file_storage.cpp | 2 +- test/test_read_resume.cpp | 2 +- test/test_remap_files.cpp | 4 +- test/test_resume.cpp | 10 ++-- test/test_storage.cpp | 8 ++-- test/test_torrent.cpp | 4 +- test/test_torrent_info.cpp | 10 ++-- test/web_seed_suite.cpp | 4 +- 29 files changed, 228 insertions(+), 92 deletions(-) create mode 100644 include/libtorrent/index_range.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 992a4e1f1..21ba25f21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ set(libtorrent_include_files http_tracker_connection i2p_stream identify_client + index_range invariant_check io io_service diff --git a/examples/connection_tester.cpp b/examples/connection_tester.cpp index 028527390..81fae43cc 100644 --- a/examples/connection_tester.cpp +++ b/examples/connection_tester.cpp @@ -1005,7 +1005,7 @@ int main(int argc, char* argv[]) const int piece_size = 1024 * 1024; lt::create_torrent t(fs, piece_size); sha1_hash zero(nullptr); - for (piece_index_t k(0); k < fs.end_piece(); ++k) + for (auto const k : fs.piece_range()) t.set_hash(k, zero); buf.clear(); diff --git a/examples/dump_torrent.cpp b/examples/dump_torrent.cpp index a42a91a1a..fc741941d 100644 --- a/examples/dump_torrent.cpp +++ b/examples/dump_torrent.cpp @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) try , t.name().c_str() , t.num_files()); lt::file_storage const& st = t.files(); - for (lt::file_index_t i(0); i < st.end_file(); ++i) + for (auto const i : st.file_range()) { auto const first = st.map_file(i, 0, 0).piece; auto const last = st.map_file(i, std::max(std::int64_t(st.file_size(i)) - 1, std::int64_t(0)), 0).piece; diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index 28d4fc75c..f7dd2a967 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -159,6 +159,7 @@ nobase_include_HEADERS = \ xml_parse.hpp \ span.hpp \ download_priority.hpp \ + index_range.hpp \ \ aux_/allocating_handler.hpp \ aux_/aligned_storage.hpp \ @@ -215,6 +216,7 @@ nobase_include_HEADERS = \ aux_/noexcept_movable.hpp \ aux_/torrent_impl.hpp \ aux_/instantiate_connection.hpp \ + aux_/range.hpp \ \ extensions/smart_ban.hpp \ extensions/ut_metadata.hpp \ diff --git a/include/libtorrent/bitfield.hpp b/include/libtorrent/bitfield.hpp index 9003cf557..5e9adc311 100644 --- a/include/libtorrent/bitfield.hpp +++ b/include/libtorrent/bitfield.hpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/assert.hpp" #include "libtorrent/config.hpp" +#include "libtorrent/index_range.hpp" #include "libtorrent/aux_/unique_ptr.hpp" #include "libtorrent/aux_/byteswap.hpp" #include "libtorrent/aux_/ffs.hpp" @@ -101,9 +102,9 @@ namespace libtorrent { } // returns true if all bits in the bitfield are set - bool all_set() const; + bool all_set() const noexcept; - bool none_set() const + bool none_set() const noexcept { if(size() == 0) return true; @@ -117,7 +118,7 @@ namespace libtorrent { } // returns the size of the bitfield in bits. - int size() const + int size() const noexcept { int const bits = m_buf == nullptr ? 0 : int(m_buf[0]); TORRENT_ASSERT(bits >= 0); @@ -156,9 +157,9 @@ namespace libtorrent { } // count the number of bits in the bitfield that are set to 1. - int count() const; - int find_first_set() const; - int find_last_clear() const; + int count() const noexcept; + int find_first_set() const noexcept; + int find_last_clear() const noexcept; struct const_iterator { @@ -282,6 +283,13 @@ namespace libtorrent { } using bitfield::bitfield; + // returns an object that can be used in a range-for to iterate over all + // indices in the bitfield + index_range range() const noexcept + { + return index_range{IndexType{0}, end_index()}; + } + bool operator[](IndexType const index) const { return this->bitfield::get_bit(static_cast(index)); } @@ -294,7 +302,7 @@ namespace libtorrent { void set_bit(IndexType const index) { this->bitfield::set_bit(static_cast(index)); } - IndexType end_index() const { return IndexType(this->size()); } + IndexType end_index() const noexcept { return IndexType(this->size()); } }; } diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index 7634deab0..d64fff47c 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/sha1_hash.hpp" #include "libtorrent/string_view.hpp" #include "libtorrent/aux_/vector.hpp" +#include "libtorrent/index_range.hpp" #include "libtorrent/flags.hpp" namespace libtorrent { @@ -106,7 +107,7 @@ namespace libtorrent { #endif // TORRENT_ABI_VERSION // internal - struct TORRENT_DEPRECATED_EXPORT internal_file_entry + struct internal_file_entry { friend class file_storage; #if TORRENT_USE_INVARIANT_CHECKS @@ -173,6 +174,7 @@ namespace libtorrent { int path_index; }; + // represents a window of a file in a torrent. // // The ``file_index`` refers to the index of the file (in the torrent_info). @@ -341,12 +343,7 @@ namespace libtorrent { TORRENT_DEPRECATED reverse_iterator rend() const { return m_files.rend(); } TORRENT_DEPRECATED - internal_file_entry const& internal_at(int index) const - { - TORRENT_ASSERT(index >= 0); - TORRENT_ASSERT(index < int(m_files.size())); - return m_files[file_index_t(index)]; - } + internal_file_entry const& internal_at(int const index) const; TORRENT_DEPRECATED file_entry at(iterator i) const; @@ -364,15 +361,15 @@ namespace libtorrent { #endif // TORRENT_ABI_VERSION // returns the number of files in the file_storage - int num_files() const - { return int(m_files.size()); } + int num_files() const noexcept; // returns the index of the one-past-end file in the file storage - file_index_t end_file() const - { return m_files.end_index(); } + file_index_t end_file() const noexcept; - file_index_t last_file() const - { return --m_files.end_index(); } + // returns an implementation-defined type that can be used as the + // container in a range-for loop. Where the values are the indices of all + // files in the file_storage. + index_range file_range() const noexcept; // returns the total number of bytes all the files in this torrent spans std::int64_t total_size() const { return m_total_size; } @@ -388,6 +385,11 @@ namespace libtorrent { piece_index_t last_piece() const { return piece_index_t(m_num_pieces - 1); } + // returns an implementation-defined type that can be used as the + // container in a range-for loop. Where the values are the indices of all + // pieces in the file_storage. + index_range piece_range() const noexcept; + // set and get the size of each piece in this torrent. This size is typically an even power // of 2. It doesn't have to be though. It should be divisible by 16 kiB however. void set_piece_length(int l) { m_piece_length = l; } @@ -403,19 +405,7 @@ namespace libtorrent { std::string const& name() const { return m_name; } // swap all content of *this* with *ti*. - void swap(file_storage& ti) noexcept - { - using std::swap; - swap(ti.m_files, m_files); - swap(ti.m_file_hashes, m_file_hashes); - swap(ti.m_symlinks, m_symlinks); - swap(ti.m_mtime, m_mtime); - swap(ti.m_paths, m_paths); - swap(ti.m_name, m_name); - swap(ti.m_total_size, m_total_size); - swap(ti.m_num_pieces, m_num_pieces); - swap(ti.m_piece_length, m_piece_length); - } + void swap(file_storage& ti) noexcept; // if pad_file_limit >= 0, files larger than that limit will be padded, // default is to not add any padding (-1). The alignment specifies the @@ -539,6 +529,8 @@ namespace libtorrent { private: + file_index_t last_file() const noexcept; + int get_or_add_path(string_view path); void add_pad_file(int size diff --git a/include/libtorrent/index_range.hpp b/include/libtorrent/index_range.hpp new file mode 100644 index 000000000..9f3ab7ca3 --- /dev/null +++ b/include/libtorrent/index_range.hpp @@ -0,0 +1,72 @@ +/* + +Copyright (c) 2018, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TORRENT_INDEX_RANGE_HPP +#define TORRENT_INDEX_RANGE_HPP + +namespace libtorrent { + +template +struct index_iter +{ + explicit index_iter(Index i) : m_idx(i) {} + index_iter operator++() + { + ++m_idx; + return *this; + } + index_iter operator--() + { + --m_idx; + return *this; + } + Index operator*() const { return m_idx; } + friend inline bool operator==(index_iter lhs, index_iter rhs) + { return lhs.m_idx == rhs.m_idx; } + friend inline bool operator!=(index_iter lhs, index_iter rhs) + { return lhs.m_idx != rhs.m_idx; } +private: + Index m_idx; +}; + +template +struct index_range +{ + Index _begin; + Index _end; + index_iter begin() { return index_iter{_begin}; } + index_iter end() { return index_iter{_end}; } +}; + +} + +#endif diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index 5f66021e6..ee86dbaa1 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -336,12 +336,17 @@ namespace libtorrent { // ``last_piece()`` returns the index to the last piece in the torrent and // ``end_piece()`` returns the index to the one-past-end piece in the // torrent + // ``piece_range()`` returns an implementation-defined type that can be + // used as the container in a range-for loop. Where the values are the + // indices of all pieces in the file_storage. piece_index_t last_piece() const { return piece_index_t(m_files.num_pieces() - 1); } piece_index_t end_piece() const { TORRENT_ASSERT(m_files.num_pieces() > 0); return piece_index_t(m_files.num_pieces()); } + index_range piece_range() const + { return m_files.piece_range(); } // returns the info-hash of the torrent const sha1_hash& info_hash() const { return m_info_hash; } diff --git a/src/bitfield.cpp b/src/bitfield.cpp index 5d81b2201..7da8f2d24 100644 --- a/src/bitfield.cpp +++ b/src/bitfield.cpp @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { - bool bitfield::all_set() const + bool bitfield::all_set() const noexcept { if(size() == 0) return false; @@ -58,7 +58,7 @@ namespace libtorrent { return true; } - int bitfield::count() const + int bitfield::count() const noexcept { int ret = 0; int const words = num_words(); @@ -193,7 +193,7 @@ namespace libtorrent { TORRENT_ASSERT(size() == bits); } - int bitfield::find_first_set() const + int bitfield::find_first_set() const noexcept { int const num = num_words(); if (num == 0) return -1; @@ -201,7 +201,7 @@ namespace libtorrent { return count != num * 32 ? count : -1; } - int bitfield::find_last_clear() const + int bitfield::find_last_clear() const noexcept { int const num = num_words(); if (num == 0) return - 1; diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index f7f5c8335..ddaf74d3a 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -432,7 +432,7 @@ namespace { } m_piece_hash.resize(m_files.num_pieces()); - for (piece_index_t i(0); i != m_files.end_piece(); ++i) + for (auto const i : m_files.piece_range()) set_hash(i, ti.hash_for_piece(i)); boost::shared_array const info = ti.metadata(); @@ -593,7 +593,7 @@ namespace { { entry& files = info["files"]; - for (file_index_t i(0); i != m_files.end_file(); ++i) + for (auto const i : m_files.file_range()) { files.list().emplace_back(); entry& file_e = files.list().back(); diff --git a/src/file_storage.cpp b/src/file_storage.cpp index a587b1cba..f41656240 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/file_storage.hpp" #include "libtorrent/string_util.hpp" // for allocate_string_copy #include "libtorrent/utf8.hpp" +#include "libtorrent/index_range.hpp" #include "libtorrent/aux_/path.hpp" #include "libtorrent/aux_/numeric_cast.hpp" @@ -503,6 +504,13 @@ namespace { return at_deprecated(index); } + internal_file_entry const& file_storage::internal_at(int const index) const + { + TORRENT_ASSERT(index >= 0); + TORRENT_ASSERT(index < int(m_files.size())); + return m_files[file_index_t(index)]; + } + file_entry file_storage::at_deprecated(int index) const { TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size())); @@ -523,6 +531,22 @@ namespace { } #endif // TORRENT_ABI_VERSION + int file_storage::num_files() const noexcept + { return int(m_files.size()); } + + // returns the index of the one-past-end file in the file storage + file_index_t file_storage::end_file() const noexcept + { return m_files.end_index(); } + + file_index_t file_storage::last_file() const noexcept + { return --m_files.end_index(); } + + index_range file_storage::file_range() const noexcept + { return {file_index_t{0}, m_files.end_index()}; } + + index_range file_storage::piece_range() const noexcept + { return {piece_index_t{0}, piece_index_t{m_num_pieces}}; } + peer_request file_storage::map_file(file_index_t const file_index , std::int64_t const file_offset, int const size) const { @@ -929,6 +953,20 @@ namespace { } } + void file_storage::swap(file_storage& ti) noexcept + { + using std::swap; + swap(ti.m_files, m_files); + swap(ti.m_file_hashes, m_file_hashes); + swap(ti.m_symlinks, m_symlinks); + swap(ti.m_mtime, m_mtime); + swap(ti.m_paths, m_paths); + swap(ti.m_name, m_name); + swap(ti.m_total_size, m_total_size); + swap(ti.m_num_pieces, m_num_pieces); + swap(ti.m_piece_length, m_piece_length); + } + void file_storage::optimize(int const pad_file_limit, int alignment , bool const tail_padding) { diff --git a/src/resolve_links.cpp b/src/resolve_links.cpp index 459b19dc5..64248f969 100644 --- a/src/resolve_links.cpp +++ b/src/resolve_links.cpp @@ -46,7 +46,7 @@ resolve_links::resolve_links(std::shared_ptr ti) file_storage const& fs = ti->files(); m_file_sizes.reserve(aux::numeric_cast(fs.num_files())); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { // don't match pad-files, and don't match files that aren't aligned to // pieces. Files are matched by comparing piece hashes, so pieces must @@ -72,7 +72,7 @@ void resolve_links::match(std::shared_ptr const& ti file_storage const& fs = ti->files(); m_file_sizes.reserve(aux::numeric_cast(fs.num_files())); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { // for every file in the other torrent, see if we have one that match // it in m_torrent_file diff --git a/src/storage.cpp b/src/storage.cpp index f8c137802..40eaa4e5e 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -274,7 +274,7 @@ namespace libtorrent { // first, create all missing directories std::string last_path; - for (file_index_t file_index(0); file_index < fs.end_file(); ++file_index) + for (auto const file_index : fs.file_range()) { // ignore files that have priority 0 if (m_file_priority.end_index() > file_index diff --git a/src/storage_utils.cpp b/src/storage_utils.cpp index 47d1139d3..5d1d1243f 100644 --- a/src/storage_utils.cpp +++ b/src/storage_utils.cpp @@ -219,7 +219,7 @@ namespace libtorrent { namespace aux { if (err != boost::system::errc::no_such_file_or_directory) { // the directory exists, check all the files - for (file_index_t i(0); i < f.end_file(); ++i) + for (auto const i : f.file_range()) { // files moved out to absolute paths are ignored if (f.file_absolute_path(i)) continue; @@ -265,9 +265,10 @@ namespace libtorrent { namespace aux { // later aux::vector copied_files(std::size_t(f.num_files()), false); - file_index_t i{}; + // track how far we got in case of an error + file_index_t file_index{}; error_code e; - for (i = file_index_t(0); i < f.end_file(); ++i) + for (auto const i : f.file_range()) { // files moved out to absolute paths are not moved if (f.file_absolute_path(i)) continue; @@ -307,6 +308,7 @@ namespace libtorrent { namespace aux { ec.ec = e; ec.file(i); ec.operation = operation_t::file_rename; + file_index = i; break; } } @@ -325,17 +327,17 @@ namespace libtorrent { namespace aux { if (e) { // rollback - while (--i >= file_index_t(0)) + while (--file_index >= file_index_t(0)) { // files moved out to absolute paths are not moved - if (f.file_absolute_path(i)) continue; + if (f.file_absolute_path(file_index)) continue; // if we ended up copying the file, don't do anything during // roll-back - if (copied_files[i]) continue; + if (copied_files[file_index]) continue; - std::string const old_path = combine_path(save_path, f.file_path(i)); - std::string const new_path = combine_path(new_save_path, f.file_path(i)); + std::string const old_path = combine_path(save_path, f.file_path(file_index)); + std::string const new_path = combine_path(new_save_path, f.file_path(file_index)); // ignore errors when rolling back error_code ignore; @@ -352,7 +354,7 @@ namespace libtorrent { namespace aux { // an in-out parameter std::set subdirs; - for (i = file_index_t(0); i < f.end_file(); ++i) + for (auto const i : f.file_range()) { // files moved out to absolute paths are not moved if (f.file_absolute_path(i)) continue; @@ -408,7 +410,7 @@ namespace libtorrent { namespace aux { // delete the files from disk std::set directories; using iter_t = std::set::iterator; - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::string const fp = fs.file_path(i); bool const complete = fs.file_absolute_path(i); @@ -480,7 +482,7 @@ namespace libtorrent { namespace aux { // moved. If so, we just fail. The user is responsible to not touch // other torrents until a new mutable torrent has been completely // added. - for (file_index_t idx(0); idx < fs.end_file(); ++idx) + for (auto const idx : fs.file_range()) { std::string const& s = links[idx]; if (s.empty()) continue; @@ -573,7 +575,7 @@ namespace libtorrent { namespace aux { , stat_cache& cache , storage_error& ec) { - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::int64_t const sz = cache.get_filesize( i, fs, save_path, ec.ec); diff --git a/src/torrent.cpp b/src/torrent.cpp index 59b2ba874..0afd792b1 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1807,7 +1807,7 @@ bool is_downloading_state(int const st) int num_pad_files = 0; TORRENT_ASSERT(block_size() > 0); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { if (fs.pad_file_at(i)) ++num_pad_files; @@ -3629,7 +3629,7 @@ bool is_downloading_state(int const st) if (m_padding > 0) { file_storage const& files = m_torrent_file->files(); - for (file_index_t i(0); i < files.end_file(); ++i) + for (auto const i : files.file_range()) { if (!files.pad_file_at(i)) continue; peer_request p = files.map_file(i, 0, int(files.file_size(i))); @@ -4506,7 +4506,7 @@ bool is_downloading_state(int const st) // do a linear search from the first piece int min_availability = 9999; std::vector avail_vec; - for (piece_index_t i(0); i < m_torrent_file->end_piece(); ++i) + for (auto const i : m_torrent_file->piece_range()) { if (bits[i]) continue; @@ -5156,7 +5156,7 @@ bool is_downloading_state(int const st) aux::vector pieces(aux::numeric_cast( m_torrent_file->num_pieces()), dont_download); file_storage const& fs = m_torrent_file->files(); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::int64_t const size = m_torrent_file->files().file_size(i); if (size == 0) continue; @@ -6287,7 +6287,7 @@ bool is_downloading_state(int const st) { file_storage const& fs = m_torrent_file->files(); file_storage const& orig_fs = m_torrent_file->orig_files(); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { if (fs.file_path(i) != orig_fs.file_path(i)) ret.renamed_files[i] = fs.file_path(i); @@ -10358,7 +10358,7 @@ bool is_downloading_state(int const st) aux::vector progress; file_progress(progress); file_storage const& fs = m_torrent_file->files(); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::int64_t file_size = m_torrent_file->files().file_size(i); if (file_size == 0) fp[i] = 1.f; @@ -10384,7 +10384,7 @@ bool is_downloading_state(int const st) { fp.resize(m_torrent_file->num_files()); file_storage const& fs = m_torrent_file->files(); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) fp[i] = fs.file_size(i); return; } diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index d065d3761..ca5cd7c94 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -615,7 +615,7 @@ namespace { // insert all directories first, to make sure no files // are allowed to collied with them m_files.all_path_hashes(files); - for (file_index_t i(0); i < m_files.end_file(); ++i) + for (auto const i : m_files.file_range()) { // as long as this file already exists // increase the counter @@ -657,7 +657,7 @@ namespace { } } - for (file_index_t i(0); i < m_files.end_file(); ++i) + for (auto const i : m_files.file_range()) { // as long as this file already exists // increase the counter @@ -1541,7 +1541,7 @@ namespace { #if TORRENT_USE_INVARIANT_CHECKS void torrent_info::check_invariant() const { - for (file_index_t i(0); i < m_files.end_file(); ++i) + for (auto const i : m_files.file_range()) { TORRENT_ASSERT(m_files.file_name_ptr(i) != nullptr); if (m_files.file_name_len(i) != -1) diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 298372e68..67e2af00f 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -153,7 +153,7 @@ void web_peer_connection::on_connected() typed_bitfield have; file_storage const& fs = t->torrent_file().files(); have.resize(fs.num_pieces(), true); - for (file_index_t i(0); i != fs.end_file(); ++i) + for (auto const i : fs.file_range()) { // if we have the file, no need to do anything if (m_web->have_files.get_bit(i) || fs.pad_file_at(i)) continue; diff --git a/test/make_torrent.cpp b/test/make_torrent.cpp index 9efd6e1bb..2eece80ac 100644 --- a/test/make_torrent.cpp +++ b/test/make_torrent.cpp @@ -184,7 +184,7 @@ void generate_files(lt::torrent_info const& ti, std::string const& path file_storage const& fs = ti.files(); std::vector buffer; - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) { int const piece_size = ti.piece_size(i); buffer.resize(static_cast(ti.piece_length())); diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index aa4a2a4cc..bfa27c48d 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -627,7 +627,7 @@ std::shared_ptr make_torrent(span const file_sizes lt::create_torrent ct(fs, piece_size, 0x4000 , lt::create_torrent::optimize_alignment); - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) { std::vector piece = generate_piece(i, fs.piece_size(i)); ct.set_hash(i, hasher(piece).final()); @@ -719,7 +719,7 @@ std::shared_ptr create_torrent(std::ostream* file // calculate the hash for all pieces sha1_hash ph = hasher(piece).final(); - for (piece_index_t i(0); i < t.files().end_piece(); ++i) + for (auto const i : fs.piece_range()) t.set_hash(i, ph); if (file) diff --git a/test/test_bitfield.cpp b/test/test_bitfield.cpp index 633a463b3..a1906b8ad 100644 --- a/test/test_bitfield.cpp +++ b/test/test_bitfield.cpp @@ -407,3 +407,15 @@ TORRENT_TEST(not_initialized_resize) test2.resize(8); TEST_EQUAL(test2.size(), 8); } + +TORRENT_TEST(bitfield_index_range) +{ + typed_bitfield b1(16); + int sum = 0; + for (auto i : b1.range()) + { + sum += i; + } + TEST_EQUAL(sum, 15 * 16 / 2); +} + diff --git a/test/test_file_progress.cpp b/test/test_file_progress.cpp index 85ff7e3f0..66b22d87a 100644 --- a/test/test_file_progress.cpp +++ b/test/test_file_progress.cpp @@ -54,7 +54,7 @@ TORRENT_TEST(init) fs.set_piece_length(piece_size); fs.set_num_pieces((int(fs.total_size()) + piece_size - 1) / piece_size); - for (piece_index_t idx(0); idx < fs.end_piece(); ++idx) + for (auto const idx : fs.piece_range()) { piece_picker picker(4, fs.total_size() % 4, fs.num_pieces()); picker.we_have(idx); @@ -85,7 +85,7 @@ TORRENT_TEST(init2) fs.set_piece_length(piece_size); fs.set_num_pieces((int(fs.total_size()) + piece_size - 1) / piece_size); - for (piece_index_t idx(0); idx < fs.end_piece(); ++idx) + for (auto const idx : fs.piece_range()) { piece_picker picker(4, fs.total_size() % 4, fs.num_pieces()); picker.we_have(idx); diff --git a/test/test_file_storage.cpp b/test/test_file_storage.cpp index 954ec7480..80a181774 100644 --- a/test/test_file_storage.cpp +++ b/test/test_file_storage.cpp @@ -450,7 +450,7 @@ void test_optimize(std::vector file_sizes if (fs.num_files() != int(expected_order.size())) return; std::cout << "{ "; - for (file_index_t idx{0}; idx != fs.end_file(); ++idx) + for (auto const idx : fs.file_range()) { if (fs.file_flags(idx) & file_storage::flag_pad_file) std::cout << "*"; std::cout << fs.file_size(idx) << " "; diff --git a/test/test_read_resume.cpp b/test/test_read_resume.cpp index 1107e8d6f..b35392fc8 100644 --- a/test/test_read_resume.cpp +++ b/test/test_read_resume.cpp @@ -184,7 +184,7 @@ std::shared_ptr generate_torrent() int num = t.num_pieces(); TEST_CHECK(num > 0); - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) { sha1_hash ph; aux::random_bytes(ph); diff --git a/test/test_remap_files.cpp b/test/test_remap_files.cpp index 110e1b31a..0a5c36a76 100644 --- a/test/test_remap_files.cpp +++ b/test/test_remap_files.cpp @@ -93,14 +93,14 @@ void test_remap_files(storage_mode_t storage_mode = storage_mode_sparse) torrent_handle tor1 = ses.add_torrent(params); // write pieces - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) { std::vector const piece = generate_piece(i, fs.piece_size(i)); tor1.add_piece(i, piece.data()); } // read pieces - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) { tor1.read_piece(i); } diff --git a/test/test_resume.cpp b/test/test_resume.cpp index 9ceb1a5c6..9362574b3 100644 --- a/test/test_resume.cpp +++ b/test/test_resume.cpp @@ -76,7 +76,7 @@ std::shared_ptr generate_torrent() t.add_url_seed("http://torrent_file_url_seed.com/"); TEST_CHECK(t.num_pieces() > 0); - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) { sha1_hash ph; aux::random_bytes(ph); @@ -388,8 +388,10 @@ void test_piece_slots_seed(settings_pack const& sett) print_alerts(ses, "ses"); TEST_EQUAL(s.info_hash, ti->info_hash()); TEST_EQUAL(s.pieces.size(), ti->num_pieces()); - for (piece_index_t i{0}; i != ti->end_piece(); ++i) + for (auto const i : ti->piece_range()) + { TEST_EQUAL(s.pieces[i], true); + } TEST_EQUAL(s.is_seeding, true); @@ -405,8 +407,10 @@ void test_piece_slots_seed(settings_pack const& sett) auto const& pieces = ra->params.have_pieces; TEST_EQUAL(int(pieces.size()), ti->num_pieces()); - for (piece_index_t i{0}; i != ti->end_piece(); ++i) + for (auto const i : ti->piece_range()) + { TEST_EQUAL(pieces[i], true); + } } } diff --git a/test/test_storage.cpp b/test/test_storage.cpp index df15d7995..99695991e 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -403,7 +403,7 @@ void test_rename(std::string const& test_path) // directories are not created up-front, unless they contain // an empty file std::string first_file = fs.file_path(file_index_t(0)); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { TEST_CHECK(!exists(combine_path(test_path, combine_path("temp_storage" , fs.file_path(i))))); @@ -517,7 +517,7 @@ void test_check_files(std::string const& test_path ios.reset(); run_until(ios, done); - for (piece_index_t i{0}; i < info->files().end_piece(); ++i) + for (auto const i : info->piece_range()) { done = false; io.async_hash(st, i, disk_interface::sequential_access | disk_interface::volatile_read @@ -817,7 +817,7 @@ TORRENT_TEST(rename_file) // make it a seed std::vector tmp(std::size_t(info->piece_length())); - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) h.add_piece(i, &tmp[0]); // wait for the files to have been written @@ -830,7 +830,7 @@ TORRENT_TEST(rename_file) } // now rename them. This is the test - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::string name = fs.file_path(i); h.rename_file(i, "temp_storage__" + name.substr(12)); diff --git a/test/test_torrent.cpp b/test/test_torrent.cpp index 83c7c1409..2d2b8949c 100644 --- a/test/test_torrent.cpp +++ b/test/test_torrent.cpp @@ -307,7 +307,7 @@ TORRENT_TEST(torrent) // calculate the hash for all pieces sha1_hash ph = hasher(piece).final(); TEST_CHECK(t.num_pieces() > 0); - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) t.set_hash(i, ph); std::vector tmp; @@ -350,7 +350,7 @@ TORRENT_TEST(duplicate_is_not_error) // calculate the hash for all pieces sha1_hash ph = hasher(piece).final(); TEST_CHECK(t.num_pieces() > 0); - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) t.set_hash(i, ph); std::vector tmp; diff --git a/test/test_torrent_info.cpp b/test/test_torrent_info.cpp index ae9a54736..7f197e1c1 100644 --- a/test/test_torrent_info.cpp +++ b/test/test_torrent_info.cpp @@ -54,7 +54,7 @@ TORRENT_TEST(mutable_torrents) // calculate the hash for all pieces sha1_hash ph; - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) t.set_hash(i, ph); t.add_collection("collection1"); @@ -902,7 +902,7 @@ void test_resolve_duplicates(int test_case) // calculate the hash for all pieces sha1_hash ph; - for (piece_index_t i(0); i < fs.end_piece(); ++i) + for (auto const i : fs.piece_range()) t.set_hash(i, ph); std::vector tmp; @@ -944,7 +944,7 @@ void test_resolve_duplicates(int test_case) } }; - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::string p = ti.files().file_path(i); convert_path_to_posix(p); @@ -1005,7 +1005,7 @@ TORRENT_TEST(copy) }; file_storage const& fs = a->files(); - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { std::string p = fs.file_path(i); convert_path_to_posix(p); @@ -1028,7 +1028,7 @@ TORRENT_TEST(copy) TEST_EQUAL(b->num_files(), 3); file_storage const& fs2 = b->files(); - for (file_index_t i(0); i < fs2.end_file(); ++i) + for (auto const i : fs2.file_range()) { std::string p = fs2.file_path(i); convert_path_to_posix(p); diff --git a/test/web_seed_suite.cpp b/test/web_seed_suite.cpp index d45ef4192..91522bb82 100644 --- a/test/web_seed_suite.cpp +++ b/test/web_seed_suite.cpp @@ -149,7 +149,7 @@ void test_transfer(lt::session& ses, std::shared_ptr torrent_file file_storage const& fs = torrent_file->files(); int pad_file_size = 0; - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { if (fs.file_flags(i) & file_storage::flag_pad_file) pad_file_size += int(fs.file_size(i)); @@ -256,7 +256,7 @@ void test_transfer(lt::session& ses, std::shared_ptr torrent_file if (!test_ban) { - for (file_index_t i(0); i < fs.end_file(); ++i) + for (auto const i : fs.file_range()) { bool const expect = !fs.pad_file_at(i); std::string file_path = combine_path(save_path, fs.file_path(i));