improve the API for iterating over all files and pieces, with the new strong index types.
This commit is contained in:
parent
596d98cac4
commit
5530793c75
|
@ -75,6 +75,7 @@ set(libtorrent_include_files
|
|||
http_tracker_connection
|
||||
i2p_stream
|
||||
identify_client
|
||||
index_range
|
||||
invariant_check
|
||||
io
|
||||
io_service
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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<IndexType> range() const noexcept
|
||||
{
|
||||
return index_range<IndexType>{IndexType{0}, end_index()};
|
||||
}
|
||||
|
||||
bool operator[](IndexType const index) const
|
||||
{ return this->bitfield::get_bit(static_cast<int>(index)); }
|
||||
|
||||
|
@ -294,7 +302,7 @@ namespace libtorrent {
|
|||
void set_bit(IndexType const index)
|
||||
{ this->bitfield::set_bit(static_cast<int>(index)); }
|
||||
|
||||
IndexType end_index() const { return IndexType(this->size()); }
|
||||
IndexType end_index() const noexcept { return IndexType(this->size()); }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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_index_t> 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_index_t> 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
|
||||
|
|
|
@ -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 <typename Index>
|
||||
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 <typename Index>
|
||||
struct index_range
|
||||
{
|
||||
Index _begin;
|
||||
Index _end;
|
||||
index_iter<Index> begin() { return index_iter<Index>{_begin}; }
|
||||
index_iter<Index> end() { return index_iter<Index>{_end}; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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_index_t> 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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<char> 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();
|
||||
|
|
|
@ -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_index_t> file_storage::file_range() const noexcept
|
||||
{ return {file_index_t{0}, m_files.end_index()}; }
|
||||
|
||||
index_range<piece_index_t> 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)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ resolve_links::resolve_links(std::shared_ptr<torrent_info> ti)
|
|||
|
||||
file_storage const& fs = ti->files();
|
||||
m_file_sizes.reserve(aux::numeric_cast<std::size_t>(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 torrent_info> const& ti
|
|||
|
||||
file_storage const& fs = ti->files();
|
||||
m_file_sizes.reserve(aux::numeric_cast<std::size_t>(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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<bool, file_index_t> 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<std::string> 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<std::string> directories;
|
||||
using iter_t = std::set<std::string>::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);
|
||||
|
|
|
@ -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<piece_index_t> 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<download_priority_t, piece_index_t> pieces(aux::numeric_cast<std::size_t>(
|
||||
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<std::int64_t, file_index_t> 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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -153,7 +153,7 @@ void web_peer_connection::on_connected()
|
|||
typed_bitfield<piece_index_t> 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;
|
||||
|
|
|
@ -184,7 +184,7 @@ void generate_files(lt::torrent_info const& ti, std::string const& path
|
|||
|
||||
file_storage const& fs = ti.files();
|
||||
std::vector<char> 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<std::size_t>(ti.piece_length()));
|
||||
|
|
|
@ -627,7 +627,7 @@ std::shared_ptr<lt::torrent_info> make_torrent(span<const int> 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<char> piece = generate_piece(i, fs.piece_size(i));
|
||||
ct.set_hash(i, hasher(piece).final());
|
||||
|
@ -719,7 +719,7 @@ std::shared_ptr<torrent_info> 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)
|
||||
|
|
|
@ -407,3 +407,15 @@ TORRENT_TEST(not_initialized_resize)
|
|||
test2.resize(8);
|
||||
TEST_EQUAL(test2.size(), 8);
|
||||
}
|
||||
|
||||
TORRENT_TEST(bitfield_index_range)
|
||||
{
|
||||
typed_bitfield<int> b1(16);
|
||||
int sum = 0;
|
||||
for (auto i : b1.range())
|
||||
{
|
||||
sum += i;
|
||||
}
|
||||
TEST_EQUAL(sum, 15 * 16 / 2);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -450,7 +450,7 @@ void test_optimize(std::vector<int> 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) << " ";
|
||||
|
|
|
@ -184,7 +184,7 @@ std::shared_ptr<torrent_info> 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);
|
||||
|
|
|
@ -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<char> 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);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ std::shared_ptr<torrent_info> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<char> 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));
|
||||
|
|
|
@ -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<char> 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<char> tmp;
|
||||
|
|
|
@ -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<char> 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);
|
||||
|
|
|
@ -149,7 +149,7 @@ void test_transfer(lt::session& ses, std::shared_ptr<torrent_info> 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_info> 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));
|
||||
|
|
Loading…
Reference in New Issue