made torrent_info reference counted and held by a boost::intrusive_ptr

This commit is contained in:
Arvid Norberg 2007-09-01 03:00:31 +00:00
parent f2c99f4160
commit c8088459a0
13 changed files with 264 additions and 238 deletions

View File

@ -87,39 +87,39 @@ int main(int argc, char* argv[])
try
{
torrent_info t;
boost::intrusive_ptr<torrent_info> t(new torrent_info);
path full_path = complete(path(argv[3]));
ofstream out(complete(path(argv[1])), std::ios_base::binary);
int piece_size = 256 * 1024;
char const* creator_str = "libtorrent";
add_files(t, full_path.branch_path(), full_path.leaf());
t.set_piece_size(piece_size);
add_files(*t, full_path.branch_path(), full_path.leaf());
t->set_piece_size(piece_size);
file_pool fp;
boost::scoped_ptr<storage_interface> st(
default_storage_constructor(t, full_path.branch_path(), fp));
t.add_tracker(argv[2]);
t->add_tracker(argv[2]);
// calculate the hash for all pieces
int num = t.num_pieces();
int num = t->num_pieces();
std::vector<char> buf(piece_size);
for (int i = 0; i < num; ++i)
{
st->read(&buf[0], i, 0, t.piece_size(i));
hasher h(&buf[0], t.piece_size(i));
t.set_hash(i, h.final());
st->read(&buf[0], i, 0, t->piece_size(i));
hasher h(&buf[0], t->piece_size(i));
t->set_hash(i, h.final());
std::cerr << (i+1) << "/" << num << "\r";
}
t.set_creator(creator_str);
t->set_creator(creator_str);
if (argc == 5)
t.add_url_seed(argv[4]);
t->add_url_seed(argv[4]);
// create the torrent and print it to out
entry e = t.create_torrent();
entry e = t->create_torrent();
libtorrent::bencode(std::ostream_iterator<char>(out), e);
}
catch (std::exception& e)

View File

@ -240,7 +240,7 @@ namespace libtorrent
bool is_listening() const;
torrent_handle add_torrent(
torrent_info const& ti
boost::intrusive_ptr<torrent_info> ti
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode

View File

@ -42,6 +42,9 @@ namespace libtorrent
template<class T>
struct intrusive_ptr_base
{
intrusive_ptr_base(const intrusive_ptr_base<T>& b)
: m_refs(0) {}
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
{
assert(s->m_refs >= 0);

View File

@ -142,6 +142,14 @@ namespace libtorrent
, entry const& resume_data = entry()
, bool compact_mode = true
, bool paused = false
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED;
torrent_handle add_torrent(
boost::intrusive_ptr<torrent_info> ti
, fs::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, bool paused = false
, storage_constructor_type sc = default_storage_constructor);
torrent_handle add_torrent(

View File

@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/limits.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/filesystem/path.hpp>
#ifdef _MSC_VER
@ -147,10 +148,11 @@ namespace libtorrent
};
typedef storage_interface* (&storage_constructor_type)(
torrent_info const&, fs::path const&
boost::intrusive_ptr<torrent_info const>, fs::path const&
, file_pool&);
TORRENT_EXPORT storage_interface* default_storage_constructor(torrent_info const& ti
TORRENT_EXPORT storage_interface* default_storage_constructor(
boost::intrusive_ptr<torrent_info const> ti
, fs::path const& path, file_pool& fp);
// returns true if the filesystem the path relies on supports
@ -169,7 +171,7 @@ namespace libtorrent
piece_manager(
boost::shared_ptr<void> const& torrent
, torrent_info const& ti
, boost::intrusive_ptr<torrent_info const> ti
, fs::path const& path
, file_pool& fp
, disk_io_thread& io
@ -227,7 +229,7 @@ namespace libtorrent
{ return m_compact_mode; }
#ifndef NDEBUG
std::string name() const { return m_info.name(); }
std::string name() const { return m_info->name(); }
#endif
private:
@ -283,7 +285,7 @@ namespace libtorrent
// a bitmask representing the pieces we have
std::vector<bool> m_have_piece;
torrent_info const& m_info;
boost::intrusive_ptr<torrent_info const> m_info;
// slots that haven't had any file storage allocated
std::vector<int> m_unallocated_slots;
@ -313,12 +315,6 @@ namespace libtorrent
mutable boost::recursive_mutex m_mutex;
bool m_allocating;
boost::mutex m_allocating_monitor;
boost::condition m_allocating_condition;
// these states are used while checking/allocating the torrent
enum {
// the default initial state
state_none,
@ -333,6 +329,11 @@ namespace libtorrent
} m_state;
int m_current_slot;
// this is saved in case we need to instantiate a new
// storage (osed when remapping files)
storage_constructor_type m_storage_constructor;
// temporary buffer used while checking
std::vector<char> m_piece_data;
// this maps a piece hash to piece index. It will be
@ -340,6 +341,8 @@ namespace libtorrent
// isn't needed)
std::multimap<sha1_hash, int> m_hash_to_piece;
// this map contains partial hashes for downloading
// pieces.
std::map<int, partial_hash> m_piece_hasher;
disk_io_thread& m_io_thread;

View File

@ -97,7 +97,7 @@ namespace libtorrent
torrent(
aux::session_impl& ses
, aux::checker_impl& checker
, torrent_info const& tf
, boost::intrusive_ptr<torrent_info> tf
, fs::path const& save_path
, tcp::endpoint const& net_interface
, bool compact_mode
@ -469,14 +469,14 @@ namespace libtorrent
bool is_seed() const
{
return valid_metadata()
&& m_num_pieces == m_torrent_file.num_pieces();
&& m_num_pieces == m_torrent_file->num_pieces();
}
// this is true if we have all the pieces that we want
bool is_finished() const
{
if (is_seed()) return true;
return valid_metadata() && m_torrent_file.num_pieces()
return valid_metadata() && m_torrent_file->num_pieces()
- m_num_pieces - m_picker->num_filtered() == 0;
}
@ -498,7 +498,7 @@ namespace libtorrent
}
piece_manager& filesystem();
torrent_info const& torrent_file() const
{ return m_torrent_file; }
{ return *m_torrent_file; }
std::vector<announce_entry> const& trackers() const
{ return m_trackers; }
@ -539,7 +539,7 @@ namespace libtorrent
bool ready_for_connections() const
{ return m_connections_initialized; }
bool valid_metadata() const
{ return m_torrent_file.is_valid(); }
{ return m_torrent_file->is_valid(); }
// parses the info section from the given
// bencoded tree and moves the torrent
@ -563,7 +563,7 @@ namespace libtorrent
void update_peer_interest();
torrent_info m_torrent_file;
boost::intrusive_ptr<torrent_info> m_torrent_file;
// is set to true when the torrent has
// been aborted.

View File

@ -57,6 +57,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/peer_request.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/intrusive_ptr_base.hpp"
namespace libtorrent
{
@ -96,7 +97,7 @@ namespace libtorrent
virtual const char* what() const throw() { return "invalid torrent file"; }
};
class TORRENT_EXPORT torrent_info
class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torrent_info>
{
public:

View File

@ -181,6 +181,19 @@ namespace libtorrent
, bool compact_mode
, bool paused
, storage_constructor_type sc)
{
boost::intrusive_ptr<torrent_info> tip(new torrent_info(ti));
return m_impl->add_torrent(tip, save_path, resume_data
, compact_mode, sc, paused);
}
torrent_handle session::add_torrent(
boost::intrusive_ptr<torrent_info> ti
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode
, bool paused
, storage_constructor_type sc)
{
return m_impl->add_torrent(ti, save_path, resume_data
, compact_mode, sc, paused);

View File

@ -1454,7 +1454,7 @@ namespace detail
}
torrent_handle session_impl::add_torrent(
torrent_info const& ti
boost::intrusive_ptr<torrent_info> ti
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode
@ -1466,7 +1466,7 @@ namespace detail
assert(m_external_listen_port > 0);
assert(!save_path.empty());
if (ti.begin_files() == ti.end_files())
if (ti->begin_files() == ti->end_files())
throw std::runtime_error("no files in torrent");
// lock the session and the checker thread (the order is important!)
@ -1479,11 +1479,11 @@ namespace detail
throw std::runtime_error("session is closing");
// is the torrent already active?
if (!find_torrent(ti.info_hash()).expired())
if (!find_torrent(ti->info_hash()).expired())
throw duplicate_torrent();
// is the torrent currently being checked?
if (m_checker_impl.find_torrent(ti.info_hash()))
if (m_checker_impl.find_torrent(ti->info_hash()))
throw duplicate_torrent();
// create the torrent and the data associated with
@ -1508,13 +1508,13 @@ namespace detail
new aux::piece_checker_data);
d->torrent_ptr = torrent_ptr;
d->save_path = save_path;
d->info_hash = ti.info_hash();
d->info_hash = ti->info_hash();
d->resume_data = resume_data;
#ifndef TORRENT_DISABLE_DHT
if (m_dht)
{
torrent_info::nodes_t const& nodes = ti.nodes();
torrent_info::nodes_t const& nodes = ti->nodes();
std::for_each(nodes.begin(), nodes.end(), bind(
(void(dht::dht_tracker::*)(std::pair<std::string, int> const&))
&dht::dht_tracker::add_node
@ -1528,7 +1528,7 @@ namespace detail
// job in its queue
m_checker_impl.m_cond.notify_one();
return torrent_handle(this, &m_checker_impl, ti.info_hash());
return torrent_handle(this, &m_checker_impl, ti->info_hash());
}
torrent_handle session_impl::add_torrent(

View File

@ -345,11 +345,11 @@ namespace libtorrent
class storage : public storage_interface, boost::noncopyable
{
public:
storage(torrent_info const& info, fs::path const& path, file_pool& fp)
storage(boost::intrusive_ptr<torrent_info const> info, fs::path const& path, file_pool& fp)
: m_info(info)
, m_files(fp)
{
assert(info.begin_files(true) != info.end_files(true));
assert(info->begin_files(true) != info->end_files(true));
m_save_path = fs::complete(path);
assert(m_save_path.is_complete());
}
@ -369,11 +369,9 @@ namespace libtorrent
size_type read_impl(char* buf, int slot, int offset, int size, bool fill_zero);
~storage()
{
m_files.release(this);
}
{ m_files.release(this); }
torrent_info const& m_info;
boost::intrusive_ptr<torrent_info const> m_info;
fs::path m_save_path;
// the file pool is typically stored in
// the session, to make all storage
@ -412,8 +410,8 @@ namespace libtorrent
{
// first, create all missing directories
fs::path last_path;
for (torrent_info::file_iterator file_iter = m_info.begin_files(true),
end_iter = m_info.end_files(true); file_iter != end_iter; ++file_iter)
for (torrent_info::file_iterator file_iter = m_info->begin_files(true),
end_iter = m_info->end_files(true); file_iter != end_iter; ++file_iter)
{
fs::path dir = (m_save_path / file_iter->path).branch_path();
@ -461,7 +459,7 @@ namespace libtorrent
void storage::write_resume_data(entry& rd) const
{
std::vector<std::pair<size_type, std::time_t> > file_sizes
= get_filesizes(m_info, m_save_path);
= get_filesizes(*m_info, m_save_path);
rd["file sizes"] = entry::list_type();
entry::list_type& fl = rd["file sizes"].list();
@ -495,7 +493,7 @@ namespace libtorrent
}
entry::list_type& slots = rd["slots"].list();
bool seed = int(slots.size()) == m_info.num_pieces()
bool seed = int(slots.size()) == m_info->num_pieces()
&& std::find_if(slots.begin(), slots.end()
, boost::bind<bool>(std::less<int>()
, boost::bind((size_type const& (entry::*)() const)
@ -510,11 +508,11 @@ namespace libtorrent
if (seed)
{
if (m_info.num_files(true) != (int)file_sizes.size())
if (m_info->num_files(true) != (int)file_sizes.size())
{
error = "the number of files does not match the torrent (num: "
+ boost::lexical_cast<std::string>(file_sizes.size()) + " actual: "
+ boost::lexical_cast<std::string>(m_info.num_files(true)) + ")";
+ boost::lexical_cast<std::string>(m_info->num_files(true)) + ")";
return false;
}
@ -522,8 +520,8 @@ namespace libtorrent
fs = file_sizes.begin();
// the resume data says we have the entire torrent
// make sure the file sizes are the right ones
for (torrent_info::file_iterator i = m_info.begin_files(true)
, end(m_info.end_files(true)); i != end; ++i, ++fs)
for (torrent_info::file_iterator i = m_info->begin_files(true)
, end(m_info->end_files(true)); i != end; ++i, ++fs)
{
if (i->size != fs->first)
{
@ -536,7 +534,7 @@ namespace libtorrent
return true;
}
return match_filesizes(m_info, m_save_path, file_sizes
return match_filesizes(*m_info, m_save_path, file_sizes
, !full_allocation_mode, &error);
}
@ -575,11 +573,11 @@ namespace libtorrent
m_files.release(this);
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION >= 103400
old_path = safe_convert((m_save_path / m_info.name()).string());
new_path = safe_convert((save_path / m_info.name()).string());
old_path = safe_convert((m_save_path / m_info->name()).string());
new_path = safe_convert((save_path / m_info->name()).string());
#else
old_path = m_save_path / m_info.name();
new_path = save_path / m_info.name();
old_path = m_save_path / m_info->name();
new_path = save_path / m_info->name();
#endif
try
@ -601,7 +599,7 @@ namespace libtorrent
/*
void storage::shuffle()
{
int num_pieces = m_info.num_pieces();
int num_pieces = m_info->num_pieces();
std::vector<int> pieces(num_pieces);
for (std::vector<int>::iterator i = pieces.begin();
@ -618,7 +616,7 @@ namespace libtorrent
{
const int slot_index = targets[i];
const int piece_index = pieces[i];
const int slot_size =static_cast<int>(m_info.piece_size(slot_index));
const int slot_size =static_cast<int>(m_info->piece_size(slot_index));
std::vector<char> buf(slot_size);
read(&buf[0], piece_index, 0, slot_size);
write(&buf[0], slot_index, 0, slot_size);
@ -629,7 +627,7 @@ namespace libtorrent
void storage::move_slot(int src_slot, int dst_slot)
{
int piece_size = m_info.piece_size(dst_slot);
int piece_size = m_info->piece_size(dst_slot);
m_scratch_buffer.resize(piece_size);
read_impl(&m_scratch_buffer[0], src_slot, 0, piece_size, true);
write(&m_scratch_buffer[0], dst_slot, 0, piece_size);
@ -638,9 +636,9 @@ namespace libtorrent
void storage::swap_slots(int slot1, int slot2)
{
// the size of the target slot is the size of the piece
int piece_size = m_info.piece_length();
int piece1_size = m_info.piece_size(slot2);
int piece2_size = m_info.piece_size(slot1);
int piece_size = m_info->piece_length();
int piece1_size = m_info->piece_size(slot2);
int piece2_size = m_info->piece_size(slot1);
m_scratch_buffer.resize(piece_size * 2);
read_impl(&m_scratch_buffer[0], slot1, 0, piece1_size, true);
read_impl(&m_scratch_buffer[piece_size], slot2, 0, piece2_size, true);
@ -651,10 +649,10 @@ namespace libtorrent
void storage::swap_slots3(int slot1, int slot2, int slot3)
{
// the size of the target slot is the size of the piece
int piece_size = m_info.piece_length();
int piece1_size = m_info.piece_size(slot2);
int piece2_size = m_info.piece_size(slot3);
int piece3_size = m_info.piece_size(slot1);
int piece_size = m_info->piece_length();
int piece1_size = m_info->piece_size(slot2);
int piece2_size = m_info->piece_size(slot3);
int piece3_size = m_info->piece_size(slot1);
m_scratch_buffer.resize(piece_size * 2);
read_impl(&m_scratch_buffer[0], slot1, 0, piece1_size, true);
read_impl(&m_scratch_buffer[piece_size], slot2, 0, piece2_size, true);
@ -681,25 +679,25 @@ namespace libtorrent
, bool fill_zero)
{
assert(buf != 0);
assert(slot >= 0 && slot < m_info.num_pieces());
assert(slot >= 0 && slot < m_info->num_pieces());
assert(offset >= 0);
assert(offset < m_info.piece_size(slot));
assert(offset < m_info->piece_size(slot));
assert(size > 0);
#ifndef NDEBUG
std::vector<file_slice> slices
= m_info.map_block(slot, offset, size, true);
= m_info->map_block(slot, offset, size, true);
assert(!slices.empty());
#endif
size_type start = slot * (size_type)m_info.piece_length() + offset;
assert(start + size <= m_info.total_size());
size_type start = slot * (size_type)m_info->piece_length() + offset;
assert(start + size <= m_info->total_size());
// find the file iterator and file offset
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_info.begin_files(true);;)
for (file_iter = m_info->begin_files(true);;)
{
if (file_offset < file_iter->size)
break;
@ -732,7 +730,7 @@ namespace libtorrent
#endif
int left_to_read = size;
int slot_size = static_cast<int>(m_info.piece_size(slot));
int slot_size = static_cast<int>(m_info->piece_size(slot));
if (offset + left_to_read > slot_size)
left_to_read = slot_size - offset;
@ -757,7 +755,7 @@ namespace libtorrent
assert(int(slices.size()) > counter);
size_type slice_size = slices[counter].size;
assert(slice_size == read_bytes);
assert(m_info.file_at(slices[counter].file_index, true).path
assert(m_info->file_at(slices[counter].file_index, true).path
== file_iter->path);
#endif
@ -807,30 +805,30 @@ namespace libtorrent
{
assert(buf != 0);
assert(slot >= 0);
assert(slot < m_info.num_pieces());
assert(slot < m_info->num_pieces());
assert(offset >= 0);
assert(size > 0);
#ifndef NDEBUG
std::vector<file_slice> slices
= m_info.map_block(slot, offset, size, true);
= m_info->map_block(slot, offset, size, true);
assert(!slices.empty());
#endif
size_type start = slot * (size_type)m_info.piece_length() + offset;
size_type start = slot * (size_type)m_info->piece_length() + offset;
// find the file iterator and file offset
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_info.begin_files(true);;)
for (file_iter = m_info->begin_files(true);;)
{
if (file_offset < file_iter->size)
break;
file_offset -= file_iter->size;
++file_iter;
assert(file_iter != m_info.end_files(true));
assert(file_iter != m_info->end_files(true));
}
fs::path p(m_save_path / file_iter->path);
@ -850,7 +848,7 @@ namespace libtorrent
}
int left_to_write = size;
int slot_size = static_cast<int>(m_info.piece_size(slot));
int slot_size = static_cast<int>(m_info->piece_size(slot));
if (offset + left_to_write > slot_size)
left_to_write = slot_size - offset;
@ -874,7 +872,7 @@ namespace libtorrent
{
assert(int(slices.size()) > counter);
assert(slices[counter].size == write_bytes);
assert(m_info.file_at(slices[counter].file_index, true).path
assert(m_info->file_at(slices[counter].file_index, true).path
== file_iter->path);
assert(buf_pos >= 0);
@ -902,7 +900,7 @@ namespace libtorrent
#endif
++file_iter;
assert(file_iter != m_info.end_files(true));
assert(file_iter != m_info->end_files(true));
fs::path p = m_save_path / file_iter->path;
file_offset = 0;
out = m_files.open_file(
@ -913,7 +911,7 @@ namespace libtorrent
}
}
storage_interface* default_storage_constructor(torrent_info const& ti
storage_interface* default_storage_constructor(boost::intrusive_ptr<torrent_info const> ti
, fs::path const& path, file_pool& fp)
{
return new storage(ti, path, fp);
@ -1027,7 +1025,7 @@ namespace libtorrent
piece_manager::piece_manager(
boost::shared_ptr<void> const& torrent
, torrent_info const& ti
, boost::intrusive_ptr<torrent_info const> ti
, fs::path const& save_path
, file_pool& fp
, disk_io_thread& io
@ -1037,7 +1035,7 @@ namespace libtorrent
, m_fill_mode(true)
, m_info(ti)
, m_save_path(complete(save_path))
, m_allocating(false)
, m_storage_constructor(sc)
, m_io_thread(io)
, m_torrent(torrent)
{
@ -1140,7 +1138,7 @@ namespace libtorrent
int slot = m_piece_to_slot[piece];
assert(slot != has_no_slot);
return m_storage->hash_for_slot(slot, ph, m_info.piece_size(piece));
return m_storage->hash_for_slot(slot, ph, m_info->piece_size(piece));
}
void piece_manager::release_files_impl()
@ -1200,7 +1198,7 @@ namespace libtorrent
int piece_manager::slot_for_piece(int piece_index) const
{
assert(piece_index >= 0 && piece_index < m_info.num_pieces());
assert(piece_index >= 0 && piece_index < m_info->num_pieces());
return m_piece_to_slot[piece_index];
}
@ -1211,13 +1209,13 @@ namespace libtorrent
try
{
assert(slot_index >= 0);
assert(slot_index < m_info.num_pieces());
assert(slot_index < m_info->num_pieces());
assert(block_size > 0);
adler32_crc crc;
std::vector<char> buf(block_size);
int num_blocks = static_cast<int>(m_info.piece_size(slot_index)) / block_size;
int last_block_size = static_cast<int>(m_info.piece_size(slot_index)) % block_size;
int num_blocks = static_cast<int>(m_info->piece_size(slot_index)) / block_size;
int last_block_size = static_cast<int>(m_info->piece_size(slot_index)) % block_size;
if (last_block_size == 0) last_block_size = block_size;
for (int i = 0; i < num_blocks-1; ++i)
@ -1310,11 +1308,11 @@ namespace libtorrent
{
// INVARIANT_CHECK;
assert((int)have_pieces.size() == m_info.num_pieces());
assert((int)have_pieces.size() == m_info->num_pieces());
const int piece_size = static_cast<int>(m_info.piece_length());
const int last_piece_size = static_cast<int>(m_info.piece_size(
m_info.num_pieces() - 1));
const int piece_size = static_cast<int>(m_info->piece_length());
const int last_piece_size = static_cast<int>(m_info->piece_size(
m_info->num_pieces() - 1));
assert((int)piece_data.size() >= last_piece_size);
@ -1470,7 +1468,7 @@ namespace libtorrent
INVARIANT_CHECK;
assert(m_info.piece_length() > 0);
assert(m_info->piece_length() > 0);
m_compact_mode = compact_mode;
@ -1480,13 +1478,13 @@ namespace libtorrent
// by check_pieces.
// m_storage->shuffle();
m_piece_to_slot.resize(m_info.num_pieces(), has_no_slot);
m_slot_to_piece.resize(m_info.num_pieces(), unallocated);
m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot);
m_slot_to_piece.resize(m_info->num_pieces(), unallocated);
m_free_slots.clear();
m_unallocated_slots.clear();
pieces.clear();
pieces.resize(m_info.num_pieces(), false);
pieces.resize(m_info->num_pieces(), false);
num_pieces = 0;
// if we have fast-resume info
@ -1591,7 +1589,7 @@ namespace libtorrent
return std::make_pair(false, 1.f);
}
if (int(m_unallocated_slots.size()) == m_info.num_pieces()
if (int(m_unallocated_slots.size()) == m_info->num_pieces()
&& !m_fill_mode)
{
// if there is not a single file on disk, just
@ -1633,8 +1631,8 @@ namespace libtorrent
assert(!m_fill_mode);
std::vector<int>().swap(m_unallocated_slots);
std::fill(m_slot_to_piece.begin(), m_slot_to_piece.end(), int(unassigned));
m_free_slots.resize(m_info.num_pieces());
for (int i = 0; i < m_info.num_pieces(); ++i)
m_free_slots.resize(m_info->num_pieces());
for (int i = 0; i < m_info->num_pieces(); ++i)
m_free_slots[i] = i;
}
@ -1654,15 +1652,15 @@ namespace libtorrent
if (m_hash_to_piece.empty())
{
m_current_slot = 0;
for (int i = 0; i < m_info.num_pieces(); ++i)
for (int i = 0; i < m_info->num_pieces(); ++i)
{
m_hash_to_piece.insert(std::make_pair(m_info.hash_for_piece(i), i));
m_hash_to_piece.insert(std::make_pair(m_info->hash_for_piece(i), i));
}
std::fill(pieces.begin(), pieces.end(), false);
}
m_piece_data.resize(int(m_info.piece_length()));
int piece_size = int(m_info.piece_size(m_current_slot));
m_piece_data.resize(int(m_info->piece_length()));
int piece_size = int(m_info->piece_size(m_current_slot));
int num_read = m_storage->read(&m_piece_data[0]
, m_current_slot, 0, piece_size);
@ -1865,9 +1863,9 @@ namespace libtorrent
{
// find the file that failed, and skip all the blocks in that file
size_type file_offset = 0;
size_type current_offset = m_current_slot * m_info.piece_length();
for (torrent_info::file_iterator i = m_info.begin_files(true);
i != m_info.end_files(true); ++i)
size_type current_offset = m_current_slot * m_info->piece_length();
for (torrent_info::file_iterator i = m_info->begin_files(true);
i != m_info->end_files(true); ++i)
{
file_offset += i->size;
if (file_offset > current_offset) break;
@ -1875,8 +1873,8 @@ namespace libtorrent
assert(file_offset > current_offset);
int skip_blocks = static_cast<int>(
(file_offset - current_offset + m_info.piece_length() - 1)
/ m_info.piece_length());
(file_offset - current_offset + m_info->piece_length() - 1)
/ m_info->piece_length());
for (int i = m_current_slot; i < m_current_slot + skip_blocks; ++i)
{
@ -1889,9 +1887,9 @@ namespace libtorrent
}
++m_current_slot;
if (m_current_slot >= m_info.num_pieces())
if (m_current_slot >= m_info->num_pieces())
{
assert(m_current_slot == m_info.num_pieces());
assert(m_current_slot == m_info->num_pieces());
// clear the memory we've been using
std::vector<char>().swap(m_piece_data);
@ -1903,7 +1901,7 @@ namespace libtorrent
assert(num_pieces == std::count(pieces.begin(), pieces.end(), true));
return std::make_pair(false, (float)m_current_slot / m_info.num_pieces());
return std::make_pair(false, (float)m_current_slot / m_info->num_pieces());
}
int piece_manager::allocate_slot_for_piece(int piece_index)
@ -1945,7 +1943,7 @@ namespace libtorrent
// special case to make sure we don't use the last slot
// when we shouldn't, since it's smaller than ordinary slots
if (*iter == m_info.num_pieces() - 1 && piece_index != *iter)
if (*iter == m_info->num_pieces() - 1 && piece_index != *iter)
{
if (m_free_slots.size() == 1)
allocate_slots(1);
@ -2050,7 +2048,7 @@ namespace libtorrent
}
else if (m_fill_mode)
{
int piece_size = int(m_info.piece_size(pos));
int piece_size = int(m_info->piece_size(pos));
int offset = 0;
for (; piece_size > 0; piece_size -= stack_buffer_size
, offset += stack_buffer_size)
@ -2076,8 +2074,8 @@ namespace libtorrent
boost::recursive_mutex::scoped_lock lock(m_mutex);
if (m_piece_to_slot.empty()) return;
assert((int)m_piece_to_slot.size() == m_info.num_pieces());
assert((int)m_slot_to_piece.size() == m_info.num_pieces());
assert((int)m_piece_to_slot.size() == m_info->num_pieces());
assert((int)m_slot_to_piece.size() == m_info->num_pieces());
for (std::vector<int>::const_iterator i = m_free_slots.begin();
i != m_free_slots.end(); ++i)
@ -2099,7 +2097,7 @@ namespace libtorrent
== m_unallocated_slots.end());
}
for (int i = 0; i < m_info.num_pieces(); ++i)
for (int i = 0; i < m_info->num_pieces(); ++i)
{
// Check domain of piece_to_slot's elements
if (m_piece_to_slot[i] != has_no_slot)
@ -2187,7 +2185,7 @@ namespace libtorrent
s << "index\tslot\tpiece\n";
for (int i = 0; i < m_info.num_pieces(); ++i)
for (int i = 0; i < m_info->num_pieces(); ++i)
{
s << i << "\t" << m_slot_to_piece[i] << "\t";
s << m_piece_to_slot[i] << "\n";

View File

@ -150,7 +150,7 @@ namespace libtorrent
torrent::torrent(
session_impl& ses
, aux::checker_impl& checker
, torrent_info const& tf
, boost::intrusive_ptr<torrent_info> tf
, fs::path const& save_path
, tcp::endpoint const& net_interface
, bool compact_mode
@ -181,7 +181,7 @@ namespace libtorrent
, m_ses(ses)
, m_checker(checker)
, m_picker(0)
, m_trackers(m_torrent_file.trackers())
, m_trackers(m_torrent_file->trackers())
, m_last_working_tracker(-1)
, m_currently_trying_tracker(0)
, m_failed_trackers(0)
@ -221,7 +221,7 @@ namespace libtorrent
, int block_size
, storage_constructor_type sc
, bool paused)
: m_torrent_file(info_hash)
: m_torrent_file(new torrent_info(info_hash))
, m_abort(false)
, m_paused(paused)
, m_just_paused(false)
@ -277,7 +277,7 @@ namespace libtorrent
if (tracker_url)
{
m_trackers.push_back(announce_entry(tracker_url));
m_torrent_file.add_tracker(tracker_url);
m_torrent_file->add_tracker(tracker_url);
}
m_policy.reset(new policy(this));
@ -286,7 +286,7 @@ namespace libtorrent
void torrent::start()
{
boost::weak_ptr<torrent> self(shared_from_this());
if (m_torrent_file.is_valid()) init();
if (m_torrent_file->is_valid()) init();
m_announce_timer.expires_from_now(seconds(1));
m_announce_timer.async_wait(m_ses.m_strand.wrap(
bind(&torrent::on_announce_disp, self, _1)));
@ -296,7 +296,7 @@ namespace libtorrent
bool torrent::should_announce_dht() const
{
// don't announce private torrents
if (m_torrent_file.is_valid() && m_torrent_file.priv()) return false;
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
if (m_trackers.empty()) return true;
@ -334,7 +334,7 @@ namespace libtorrent
std::string torrent::name() const
{
if (valid_metadata()) return m_torrent_file.name();
if (valid_metadata()) return m_torrent_file->name();
if (m_name) return *m_name;
return "";
}
@ -350,22 +350,22 @@ namespace libtorrent
// shared_from_this()
void torrent::init()
{
assert(m_torrent_file.is_valid());
assert(m_torrent_file.num_files() > 0);
assert(m_torrent_file.total_size() >= 0);
assert(m_torrent_file->is_valid());
assert(m_torrent_file->num_files() > 0);
assert(m_torrent_file->total_size() >= 0);
m_have_pieces.resize(m_torrent_file.num_pieces(), false);
m_have_pieces.resize(m_torrent_file->num_pieces(), false);
// the shared_from_this() will create an intentional
// cycle of ownership, se the hpp file for description.
m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file
, m_save_path, m_ses.m_files, m_ses.m_disk_thread, m_storage_constructor);
m_storage = m_owning_storage.get();
m_block_size = calculate_block_size(m_torrent_file, m_default_block_size);
m_block_size = calculate_block_size(*m_torrent_file, m_default_block_size);
m_picker.reset(new piece_picker(
static_cast<int>(m_torrent_file.piece_length() / m_block_size)
, static_cast<int>((m_torrent_file.total_size()+m_block_size-1)/m_block_size)));
static_cast<int>(m_torrent_file->piece_length() / m_block_size)
, static_cast<int>((m_torrent_file->total_size()+m_block_size-1)/m_block_size)));
std::vector<std::string> const& url_seeds = m_torrent_file.url_seeds();
std::vector<std::string> const& url_seeds = m_torrent_file->url_seeds();
std::copy(url_seeds.begin(), url_seeds.end(), std::inserter(m_web_seeds
, m_web_seeds.begin()));
}
@ -393,7 +393,7 @@ namespace libtorrent
{
boost::weak_ptr<torrent> self(shared_from_this());
if (!m_torrent_file.priv())
if (!m_torrent_file->priv())
{
// announce on local network every 5 minutes
m_announce_timer.expires_from_now(minutes(5));
@ -401,7 +401,7 @@ namespace libtorrent
bind(&torrent::on_announce_disp, self, _1)));
// announce with the local discovery service
m_ses.announce_lsd(m_torrent_file.info_hash());
m_ses.announce_lsd(m_torrent_file->info_hash());
}
else
{
@ -419,7 +419,7 @@ namespace libtorrent
// TODO: There should be a way to abort an announce operation on the dht.
// when the torrent is destructed
assert(m_ses.m_external_listen_port > 0);
m_ses.m_dht->announce(m_torrent_file.info_hash()
m_ses.m_dht->announce(m_torrent_file->info_hash()
, m_ses.m_external_listen_port
, m_ses.m_strand.wrap(bind(&torrent::on_dht_announce_response_disp, self, _1)));
}
@ -465,7 +465,7 @@ namespace libtorrent
{
INVARIANT_CHECK;
if (m_torrent_file.trackers().empty()) return false;
if (m_torrent_file->trackers().empty()) return false;
if (m_just_paused)
{
@ -615,7 +615,7 @@ namespace libtorrent
// if we don't have the metadata yet, we
// cannot tell how big the torrent is.
if (!valid_metadata()) return -1;
return m_torrent_file.total_size()
return m_torrent_file->total_size()
- quantized_bytes_done();
}
@ -625,23 +625,23 @@ namespace libtorrent
if (!valid_metadata()) return 0;
if (m_torrent_file.num_pieces() == 0)
if (m_torrent_file->num_pieces() == 0)
return 0;
if (is_seed()) return m_torrent_file.total_size();
if (is_seed()) return m_torrent_file->total_size();
const int last_piece = m_torrent_file.num_pieces() - 1;
const int last_piece = m_torrent_file->num_pieces() - 1;
size_type total_done
= m_num_pieces * m_torrent_file.piece_length();
= m_num_pieces * m_torrent_file->piece_length();
// if we have the last piece, we have to correct
// the amount we have, since the first calculation
// assumed all pieces were of equal size
if (m_have_pieces[last_piece])
{
int corr = m_torrent_file.piece_size(last_piece)
- m_torrent_file.piece_length();
int corr = m_torrent_file->piece_size(last_piece)
- m_torrent_file->piece_length();
total_done += corr;
}
return total_done;
@ -654,42 +654,42 @@ namespace libtorrent
{
INVARIANT_CHECK;
if (!valid_metadata() || m_torrent_file.num_pieces() == 0)
if (!valid_metadata() || m_torrent_file->num_pieces() == 0)
return tuple<size_type, size_type>(0,0);
const int last_piece = m_torrent_file.num_pieces() - 1;
const int last_piece = m_torrent_file->num_pieces() - 1;
if (is_seed())
return make_tuple(m_torrent_file.total_size()
, m_torrent_file.total_size());
return make_tuple(m_torrent_file->total_size()
, m_torrent_file->total_size());
size_type wanted_done = (m_num_pieces - m_picker->num_have_filtered())
* m_torrent_file.piece_length();
* m_torrent_file->piece_length();
size_type total_done
= m_num_pieces * m_torrent_file.piece_length();
assert(m_num_pieces < m_torrent_file.num_pieces());
= m_num_pieces * m_torrent_file->piece_length();
assert(m_num_pieces < m_torrent_file->num_pieces());
// if we have the last piece, we have to correct
// the amount we have, since the first calculation
// assumed all pieces were of equal size
if (m_have_pieces[last_piece])
{
int corr = m_torrent_file.piece_size(last_piece)
- m_torrent_file.piece_length();
int corr = m_torrent_file->piece_size(last_piece)
- m_torrent_file->piece_length();
total_done += corr;
if (m_picker->piece_priority(last_piece) != 0)
wanted_done += corr;
}
assert(total_done <= m_torrent_file.total_size());
assert(wanted_done <= m_torrent_file.total_size());
assert(total_done <= m_torrent_file->total_size());
assert(wanted_done <= m_torrent_file->total_size());
const std::vector<piece_picker::downloading_piece>& dl_queue
= m_picker->get_download_queue();
const int blocks_per_piece = static_cast<int>(
m_torrent_file.piece_length() / m_block_size);
m_torrent_file->piece_length() / m_block_size);
for (std::vector<piece_picker::downloading_piece>::const_iterator i =
dl_queue.begin(); i != dl_queue.end(); ++i)
@ -722,15 +722,15 @@ namespace libtorrent
== piece_picker::block_info::state_finished)
{
corr -= m_block_size;
corr += m_torrent_file.piece_size(last_piece) % m_block_size;
corr += m_torrent_file->piece_size(last_piece) % m_block_size;
}
total_done += corr;
if (m_picker->piece_priority(index) != 0)
wanted_done += corr;
}
assert(total_done <= m_torrent_file.total_size());
assert(wanted_done <= m_torrent_file.total_size());
assert(total_done <= m_torrent_file->total_size());
assert(wanted_done <= m_torrent_file->total_size());
std::map<piece_block, int> downloading_piece;
for (const_peer_iterator i = begin(); i != end(); ++i)
@ -760,10 +760,10 @@ namespace libtorrent
}
#ifndef NDEBUG
assert(p->bytes_downloaded <= p->full_block_bytes);
int last_piece = m_torrent_file.num_pieces() - 1;
int last_piece = m_torrent_file->num_pieces() - 1;
if (p->piece_index == last_piece
&& p->block_index == m_torrent_file.piece_size(last_piece) / block_size())
assert(p->full_block_bytes == m_torrent_file.piece_size(last_piece) % block_size());
&& p->block_index == m_torrent_file->piece_size(last_piece) / block_size())
assert(p->full_block_bytes == m_torrent_file->piece_size(last_piece) % block_size());
else
assert(p->full_block_bytes == block_size());
#endif
@ -779,7 +779,7 @@ namespace libtorrent
#ifndef NDEBUG
if (total_done >= m_torrent_file.total_size())
if (total_done >= m_torrent_file->total_size())
{
std::copy(m_have_pieces.begin(), m_have_pieces.end()
, std::ostream_iterator<bool>(std::cerr, " "));
@ -810,8 +810,8 @@ namespace libtorrent
}
assert(total_done <= m_torrent_file.total_size());
assert(wanted_done <= m_torrent_file.total_size());
assert(total_done <= m_torrent_file->total_size());
assert(wanted_done <= m_torrent_file->total_size());
#endif
@ -908,14 +908,14 @@ namespace libtorrent
// think that it has received all of it until this function
// resets the download queue. So, we cannot do the
// invariant check here since it assumes:
// (total_done == m_torrent_file.total_size()) => is_seed()
// (total_done == m_torrent_file->total_size()) => is_seed()
// INVARIANT_CHECK;
assert(m_storage);
assert(m_storage->refcount() > 0);
assert(m_picker.get());
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
assert(index < m_torrent_file->num_pieces());
if (m_ses.m_alerts.should_post(alert::info))
{
@ -924,7 +924,7 @@ namespace libtorrent
m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index, s.str()));
}
// increase the total amount of failed bytes
m_total_failed_bytes += m_torrent_file.piece_size(index);
m_total_failed_bytes += m_torrent_file->piece_size(index);
std::vector<void*> downloaders;
m_picker->get_downloaders(downloaders, index);
@ -1047,7 +1047,7 @@ namespace libtorrent
// INVARIANT_CHECK;
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
assert(index < m_torrent_file->num_pieces());
std::vector<void*> downloaders;
m_picker->get_downloaders(downloaders, index);
@ -1090,7 +1090,7 @@ namespace libtorrent
if (is_seed())
{
m_picker.reset();
m_torrent_file.seed_free();
m_torrent_file->seed_free();
}
}
@ -1124,7 +1124,7 @@ namespace libtorrent
// this call is only valid on torrents with metadata
assert(m_picker.get());
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
assert(index < m_torrent_file->num_pieces());
bool filter_updated = m_picker->set_piece_priority(index, priority);
if (filter_updated) update_peer_interest();
@ -1140,7 +1140,7 @@ namespace libtorrent
// this call is only valid on torrents with metadata
assert(m_picker.get());
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
assert(index < m_torrent_file->num_pieces());
return m_picker->piece_priority(index);
}
@ -1176,7 +1176,7 @@ namespace libtorrent
if (is_seed())
{
pieces.clear();
pieces.resize(m_torrent_file.num_pieces(), 1);
pieces.resize(m_torrent_file->num_pieces(), 1);
return;
}
@ -1201,20 +1201,20 @@ namespace libtorrent
// the bitmask need to have exactly one bit for every file
// in the torrent
assert(int(files.size()) == m_torrent_file.num_files());
assert(int(files.size()) == m_torrent_file->num_files());
size_type position = 0;
if (m_torrent_file.num_pieces() == 0) return;
if (m_torrent_file->num_pieces() == 0) return;
int piece_length = m_torrent_file.piece_length();
int piece_length = m_torrent_file->piece_length();
// initialize the piece priorities to 0, then only allow
// setting higher priorities
std::vector<int> pieces(m_torrent_file.num_pieces(), 0);
std::vector<int> pieces(m_torrent_file->num_pieces(), 0);
for (int i = 0; i < int(files.size()); ++i)
{
size_type start = position;
size_type size = m_torrent_file.file_at(i).size;
size_type size = m_torrent_file->file_at(i).size;
if (size == 0) continue;
position += size;
// mark all pieces of the file with this file's priority
@ -1250,7 +1250,7 @@ namespace libtorrent
// this call is only valid on torrents with metadata
assert(m_picker.get());
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
assert(index < m_torrent_file->num_pieces());
m_picker->set_piece_priority(index, filter ? 1 : 0);
update_peer_interest();
@ -1287,7 +1287,7 @@ namespace libtorrent
assert(m_picker.get());
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
assert(index < m_torrent_file->num_pieces());
return m_picker->piece_priority(index) == 0;
}
@ -1301,7 +1301,7 @@ namespace libtorrent
if (is_seed())
{
bitmask.clear();
bitmask.resize(m_torrent_file.num_pieces(), false);
bitmask.resize(m_torrent_file->num_pieces(), false);
return;
}
@ -1318,20 +1318,20 @@ namespace libtorrent
// the bitmask need to have exactly one bit for every file
// in the torrent
assert((int)bitmask.size() == m_torrent_file.num_files());
assert((int)bitmask.size() == m_torrent_file->num_files());
size_type position = 0;
if (m_torrent_file.num_pieces())
if (m_torrent_file->num_pieces())
{
int piece_length = m_torrent_file.piece_length();
int piece_length = m_torrent_file->piece_length();
// mark all pieces as filtered, then clear the bits for files
// that should be downloaded
std::vector<bool> piece_filter(m_torrent_file.num_pieces(), true);
std::vector<bool> piece_filter(m_torrent_file->num_pieces(), true);
for (int i = 0; i < (int)bitmask.size(); ++i)
{
size_type start = position;
position += m_torrent_file.file_at(i).size;
position += m_torrent_file->file_at(i).size;
// is the file selected for download?
if (!bitmask[i])
{
@ -1366,7 +1366,7 @@ namespace libtorrent
m_next_request = time_now() + seconds(tracker_retry_delay_max);
tracker_request req;
req.info_hash = m_torrent_file.info_hash();
req.info_hash = m_torrent_file->info_hash();
req.pid = m_ses.get_peer_id();
req.downloaded = m_stat.total_payload_download();
req.uploaded = m_stat.total_payload_upload();
@ -1890,8 +1890,8 @@ namespace libtorrent
{
INVARIANT_CHECK;
assert(!m_torrent_file.is_valid());
m_torrent_file.parse_info_section(metadata);
assert(!m_torrent_file->is_valid());
m_torrent_file->parse_info_section(metadata);
init();
@ -1901,12 +1901,12 @@ namespace libtorrent
new aux::piece_checker_data);
d->torrent_ptr = shared_from_this();
d->save_path = m_save_path;
d->info_hash = m_torrent_file.info_hash();
d->info_hash = m_torrent_file->info_hash();
// add the torrent to the queue to be checked
m_checker.m_torrents.push_back(d);
typedef session_impl::torrent_map torrent_map;
torrent_map::iterator i = m_ses.m_torrents.find(
m_torrent_file.info_hash());
m_torrent_file->info_hash());
assert(i != m_ses.m_torrents.end());
m_ses.m_torrents.erase(i);
// and notify the thread that it got another
@ -2291,7 +2291,7 @@ namespace libtorrent
if (is_seed())
{
m_picker.reset();
m_torrent_file.seed_free();
m_torrent_file->seed_free();
}
if (!m_connections_initialized)
@ -2374,7 +2374,7 @@ namespace libtorrent
torrent_handle torrent::get_handle() const
{
return torrent_handle(&m_ses, &m_checker, m_torrent_file.info_hash());
return torrent_handle(&m_ses, &m_checker, m_torrent_file->info_hash());
}
session_settings const& torrent::settings() const
@ -2417,7 +2417,7 @@ namespace libtorrent
if (valid_metadata())
{
assert(m_abort || int(m_have_pieces.size()) == m_torrent_file.num_pieces());
assert(m_abort || int(m_have_pieces.size()) == m_torrent_file->num_pieces());
}
else
{
@ -2425,12 +2425,12 @@ namespace libtorrent
}
size_type total_done = quantized_bytes_done();
if (m_torrent_file.is_valid())
if (m_torrent_file->is_valid())
{
if (is_seed())
assert(total_done == m_torrent_file.total_size());
assert(total_done == m_torrent_file->total_size());
else
assert(total_done != m_torrent_file.total_size());
assert(total_done != m_torrent_file->total_size());
}
else
{
@ -2441,7 +2441,7 @@ namespace libtorrent
assert(m_num_pieces
== std::count(m_have_pieces.begin(), m_have_pieces.end(), true));
assert(!valid_metadata() || m_block_size > 0);
assert(!valid_metadata() || (m_torrent_file.piece_length() % m_block_size) == 0);
assert(!valid_metadata() || (m_torrent_file->piece_length() % m_block_size) == 0);
// if (is_seed()) assert(m_picker.get() == 0);
}
#endif
@ -2678,7 +2678,7 @@ namespace libtorrent
assert(m_storage);
assert(m_storage->refcount() > 0);
assert(piece_index >= 0);
assert(piece_index < m_torrent_file.num_pieces());
assert(piece_index < m_torrent_file->num_pieces());
assert(piece_index < (int)m_have_pieces.size());
m_storage->async_hash(piece_index, bind(&torrent::on_piece_verified
@ -2690,7 +2690,7 @@ namespace libtorrent
{
sha1_hash h(j.str);
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
f(m_torrent_file.hash_for_piece(j.piece) == h);
f(m_torrent_file->hash_for_piece(j.piece) == h);
}
const tcp::endpoint& torrent::current_tracker() const
@ -2706,12 +2706,12 @@ namespace libtorrent
assert(valid_metadata());
fp.clear();
fp.resize(m_torrent_file.num_files(), 0.f);
fp.resize(m_torrent_file->num_files(), 0.f);
for (int i = 0; i < m_torrent_file.num_files(); ++i)
for (int i = 0; i < m_torrent_file->num_files(); ++i)
{
peer_request ret = m_torrent_file.map_file(i, 0, 0);
size_type size = m_torrent_file.file_at(i).size;
peer_request ret = m_torrent_file->map_file(i, 0, 0);
size_type size = m_torrent_file->file_at(i).size;
// zero sized files are considered
// 100% done all the time
@ -2724,7 +2724,7 @@ namespace libtorrent
size_type done = 0;
while (size > 0)
{
size_type bytes_step = (std::min)(m_torrent_file.piece_size(ret.piece)
size_type bytes_step = (std::min)(m_torrent_file->piece_size(ret.piece)
- ret.start, size);
if (m_have_pieces[ret.piece]) done += bytes_step;
++ret.piece;
@ -2733,7 +2733,7 @@ namespace libtorrent
}
assert(size == 0);
fp[i] = static_cast<float>(done) / m_torrent_file.file_at(i).size;
fp[i] = static_cast<float>(done) / m_torrent_file->file_at(i).size;
}
}
@ -2820,21 +2820,21 @@ namespace libtorrent
// fill in status that depends on metadata
st.total_wanted = m_torrent_file.total_size();
st.total_wanted = m_torrent_file->total_size();
if (m_picker.get() && (m_picker->num_filtered() > 0
|| m_picker->num_have_filtered() > 0))
{
int filtered_pieces = m_picker->num_filtered()
+ m_picker->num_have_filtered();
int last_piece_index = m_torrent_file.num_pieces() - 1;
int last_piece_index = m_torrent_file->num_pieces() - 1;
if (m_picker->piece_priority(last_piece_index) == 0)
{
st.total_wanted -= m_torrent_file.piece_size(last_piece_index);
st.total_wanted -= m_torrent_file->piece_size(last_piece_index);
--filtered_pieces;
}
st.total_wanted -= filtered_pieces * m_torrent_file.piece_length();
st.total_wanted -= filtered_pieces * m_torrent_file->piece_length();
}
assert(st.total_wanted >= st.total_wanted_done);
@ -2852,7 +2852,7 @@ namespace libtorrent
}
else if (is_seed())
{
assert(st.total_done == m_torrent_file.total_size());
assert(st.total_done == m_torrent_file->total_size());
st.state = torrent_status::seeding;
}
else if (st.total_wanted_done == st.total_wanted)

View File

@ -23,7 +23,7 @@ void on_read_piece(int ret, disk_io_job const& j, char const* data, int size)
TEST_CHECK(std::equal(j.buffer, j.buffer + ret, data));
}
void run_storage_tests(torrent_info& info, bool compact_allocation = true)
void run_storage_tests(boost::intrusive_ptr<torrent_info> info, bool compact_allocation = true)
{
const int half = piece_size / 2;
@ -39,16 +39,16 @@ void run_storage_tests(torrent_info& info, bool compact_allocation = true)
{ 0, 0, 1, 0, 0, 0, 0, 0
, 1, 1, 1, 1, 1, 1, 1, 1};
info.set_hash(0, hasher(piece0, piece_size).final());
info.set_hash(1, hasher(piece1, piece_size).final());
info.set_hash(2, hasher(piece2, piece_size).final());
info->set_hash(0, hasher(piece0, piece_size).final());
info->set_hash(1, hasher(piece1, piece_size).final());
info->set_hash(2, hasher(piece2, piece_size).final());
info.create_torrent();
info->create_torrent();
create_directory(initial_path() / "temp_storage");
int num_pieces = (1 + 612 + 17 + piece_size - 1) / piece_size;
TEST_CHECK(info.num_pieces() == num_pieces);
TEST_CHECK(info->num_pieces() == num_pieces);
char piece[piece_size];
@ -131,13 +131,13 @@ void run_storage_tests(torrent_info& info, bool compact_allocation = true)
int test_main()
{
torrent_info info;
info.set_piece_size(piece_size);
info.add_file("temp_storage/test1.tmp", 17);
info.add_file("temp_storage/test2.tmp", 612);
info.add_file("temp_storage/test3.tmp", 0);
info.add_file("temp_storage/test4.tmp", 0);
info.add_file("temp_storage/test5.tmp", 1);
boost::intrusive_ptr<torrent_info> info(new torrent_info());
info->set_piece_size(piece_size);
info->add_file("temp_storage/test1.tmp", 17);
info->add_file("temp_storage/test2.tmp", 612);
info->add_file("temp_storage/test3.tmp", 0);
info->add_file("temp_storage/test4.tmp", 0);
info->add_file("temp_storage/test5.tmp", 1);
run_storage_tests(info);
@ -155,7 +155,7 @@ int test_main()
// make sure remap_files works
std::vector<std::pair<std::string, libtorrent::size_type> > map;
map.push_back(std::make_pair(std::string("temp_storage/test.tmp"), 17 + 612 + 1));
bool ret = info.remap_files(map);
bool ret = info->remap_files(map);
TEST_CHECK(ret);
run_storage_tests(info, false);
@ -167,9 +167,9 @@ int test_main()
// ==============================================
info = torrent_info();
info.set_piece_size(piece_size);
info.add_file("temp_storage/test1.tmp", 17 + 612 + 1);
info = new torrent_info();
info->set_piece_size(piece_size);
info->add_file("temp_storage/test1.tmp", 17 + 612 + 1);
run_storage_tests(info);

View File

@ -37,27 +37,27 @@ void test_transfer()
{
using namespace libtorrent;
torrent_info torrent_file;
torrent_file.add_url_seed("http://127.0.0.1/bravia_paint_ad_70sec_1280x720.mov");
boost::intrusive_ptr<torrent_info> torrent_file(new torrent_info);
torrent_file->add_url_seed("http://127.0.0.1/bravia_paint_ad_70sec_1280x720.mov");
path full_path = "/Library/WebServer/Documents/bravia_paint_ad_70sec_1280x720.mov";
add_files(torrent_file, full_path.branch_path(), full_path.leaf());
add_files(*torrent_file, full_path.branch_path(), full_path.leaf());
file_pool fp;
boost::scoped_ptr<storage_interface> s(default_storage_constructor(
torrent_file, full_path.branch_path(), fp));
// calculate the hash for all pieces
int num = torrent_file.num_pieces();
std::vector<char> buf(torrent_file.piece_length());
int num = torrent_file->num_pieces();
std::vector<char> buf(torrent_file->piece_length());
for (int i = 0; i < num; ++i)
{
s->read(&buf[0], i, 0, torrent_file.piece_size(i));
hasher h(&buf[0], torrent_file.piece_size(i));
torrent_file.set_hash(i, h.final());
s->read(&buf[0], i, 0, torrent_file->piece_size(i));
hasher h(&buf[0], torrent_file->piece_size(i));
torrent_file->set_hash(i, h.final());
}
// to calculate the info_hash
entry te = torrent_file.create_torrent();
entry te = torrent_file->create_torrent();
te.print(std::cout);
// std::ofstream torrent("web_seed.torrent", std::ios::binary | std::ios::trunc);