forked from premiere/premiere-libtorrent
*** empty log message ***
This commit is contained in:
parent
c094bc98b5
commit
080da58903
|
@ -357,14 +357,16 @@ the <tt class="docutils literal"><span class="pre">session</span></tt>, it conta
|
|||
entry const& e
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
void remove_torrent(torrent_handle const& h);
|
||||
|
||||
|
@ -430,13 +432,16 @@ torrent_handle add_torrent(
|
|||
entry const& e
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>You add torrents through the <tt class="docutils literal"><span class="pre">add_torrent()</span></tt> function where you give an
|
||||
|
@ -455,6 +460,10 @@ are rearranged to finally be in their correct places once the entire torrent has
|
|||
downloaded. If it is false, the entire storage is allocated before download begins. I.e.
|
||||
the files contained in the torrent are filled with zeroes, and each downloaded piece
|
||||
is put in its final place directly when downloaded.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">block_size</span></tt> sets the preferred request size, i.e. the number of bytes to request from
|
||||
a peer at a time. This block size must be a divisor of the piece size, and since the piece
|
||||
size is an even power of 2, so must the block size be. If the block size given here turns
|
||||
out to be greater than the piece size, it will simply be clamped to the piece size.</p>
|
||||
<p>The <a class="reference" href="#torrent-handle">torrent_handle</a> returned by <tt class="docutils literal"><span class="pre">add_torrent()</span></tt> can be used to retrieve information
|
||||
about the torrent's progress, its peers etc. It is also used to abort a torrent.</p>
|
||||
<p>The second overload that takes a tracker url and an info-hash instead of metadata (<tt class="docutils literal"><span class="pre">entry</span></tt>)
|
||||
|
|
|
@ -226,14 +226,16 @@ The ``session`` class has the following synopsis::
|
|||
entry const& e
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
void remove_torrent(torrent_handle const& h);
|
||||
|
||||
|
@ -303,13 +305,16 @@ add_torrent()
|
|||
entry const& e
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
You add torrents through the ``add_torrent()`` function where you give an
|
||||
object representing the information found in the torrent file and the path where you
|
||||
|
@ -331,6 +336,11 @@ downloaded. If it is false, the entire storage is allocated before download begi
|
|||
the files contained in the torrent are filled with zeroes, and each downloaded piece
|
||||
is put in its final place directly when downloaded.
|
||||
|
||||
``block_size`` sets the preferred request size, i.e. the number of bytes to request from
|
||||
a peer at a time. This block size must be a divisor of the piece size, and since the piece
|
||||
size is an even power of 2, so must the block size be. If the block size given here turns
|
||||
out to be greater than the piece size, it will simply be clamped to the piece size.
|
||||
|
||||
The torrent_handle_ returned by ``add_torrent()`` can be used to retrieve information
|
||||
about the torrent's progress, its peers etc. It is also used to abort a torrent.
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ int main(int argc, char* argv[])
|
|||
catch (invalid_encoding&) {}
|
||||
catch (boost::filesystem::filesystem_error&) {}
|
||||
|
||||
handles.push_back(ses.add_torrent(e, save_path, resume_data));
|
||||
handles.push_back(ses.add_torrent(e, save_path, resume_data, true, 128 * 1024));
|
||||
handles.back().set_max_connections(100);
|
||||
handles.back().set_max_uploads(-1);
|
||||
handles.back().set_ratio(1.02f);
|
||||
|
|
|
@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -51,7 +52,7 @@ public:
|
|||
ip_filter();
|
||||
void add_rule(address first, address last, int flags);
|
||||
int access(address const& addr) const;
|
||||
//void print() const;
|
||||
void print() const;
|
||||
|
||||
private:
|
||||
struct range
|
||||
|
|
|
@ -317,14 +317,16 @@ namespace libtorrent
|
|||
entry const& metadata
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true);
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024);
|
||||
|
||||
session_status status() const;
|
||||
|
||||
|
|
|
@ -96,7 +96,8 @@ namespace libtorrent
|
|||
, entry const& metadata
|
||||
, boost::filesystem::path const& save_path
|
||||
, address const& net_interface
|
||||
, bool compact_mode);
|
||||
, bool compact_mode
|
||||
, int block_size);
|
||||
|
||||
// used with metadata-less torrents
|
||||
// (the metadata is downloaded from the peers)
|
||||
|
@ -106,7 +107,8 @@ namespace libtorrent
|
|||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, address const& net_interface
|
||||
, bool compact_mode);
|
||||
, bool compact_mode
|
||||
, int block_size);
|
||||
|
||||
~torrent();
|
||||
|
||||
|
@ -525,6 +527,10 @@ namespace libtorrent
|
|||
|
||||
int m_metadata_progress;
|
||||
int m_metadata_size;
|
||||
|
||||
// defaults to 16 kiB, but can be set by the user
|
||||
// when creating the torrent
|
||||
const int m_default_block_size;
|
||||
};
|
||||
|
||||
inline boost::posix_time::ptime torrent::next_announce() const
|
||||
|
|
|
@ -59,12 +59,15 @@ namespace libtorrent
|
|||
assert(j != i);
|
||||
|
||||
int first_access = i->access;
|
||||
/*
|
||||
|
||||
std::cout << "flags: " << flags << "\n";
|
||||
std::cout << "first_access: " << first_access << "\n";
|
||||
std::cout << "i->start: " << i->start.as_string() << "\n";
|
||||
std::cout << "first: " << first.as_string() << "\n";
|
||||
*/
|
||||
|
||||
int last_access = last_access = prior(j)->access;
|
||||
std::cout << "last_access: " << last_access << "\n";
|
||||
|
||||
if (i->start != first && first_access != flags)
|
||||
{
|
||||
i = m_access_list.insert(i, range(address(first.ip(), 0), flags));
|
||||
|
@ -74,22 +77,20 @@ namespace libtorrent
|
|||
--i;
|
||||
first_access = i->access;
|
||||
}
|
||||
/*
|
||||
|
||||
std::cout << "distance(i, j): " << std::distance(i, j) << "\n";
|
||||
std::cout << "size(): " << m_access_list.size() << "\n";
|
||||
*/
|
||||
|
||||
assert(!m_access_list.empty());
|
||||
assert(i != m_access_list.end());
|
||||
int last_access = last_access = prior(j)->access;
|
||||
|
||||
// std::cout << "last_access: " << last_access << "\n";
|
||||
if (i != j)
|
||||
m_access_list.erase(next(i), j);
|
||||
/*
|
||||
|
||||
std::cout << "size(): " << m_access_list.size() << "\n";
|
||||
std::cout << "last: " << last.as_string() << "\n";
|
||||
std::cout << "last.ip(): " << last.ip() << " " << 0xffffffff << "\n";
|
||||
*/
|
||||
|
||||
if (i->start == first)
|
||||
{
|
||||
// we can do this const-cast because we know that the new
|
||||
|
@ -106,6 +107,7 @@ namespace libtorrent
|
|||
|| (j == m_access_list.end() && last.ip() != 0xffffffff))
|
||||
{
|
||||
assert(j == m_access_list.end() || last.ip() < j->start.ip() - 1);
|
||||
std::cout << " -- last_access: " << last_access << "\n";
|
||||
if (last_access != flags)
|
||||
j = m_access_list.insert(j, range(address(last.ip() + 1, 0), last_access));
|
||||
}
|
||||
|
@ -124,7 +126,7 @@ namespace libtorrent
|
|||
|| addr < boost::next(i)->start));
|
||||
return i->access;
|
||||
}
|
||||
/*
|
||||
|
||||
void ip_filter::print() const
|
||||
{
|
||||
for (range_t::iterator i = m_access_list.begin(); i != m_access_list.end(); ++i)
|
||||
|
@ -132,6 +134,6 @@ namespace libtorrent
|
|||
std::cout << i->start.as_string() << " " << i->access << "\n";
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
175
src/session.cpp
175
src/session.cpp
|
@ -963,8 +963,22 @@ namespace libtorrent
|
|||
entry const& metadata
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode)
|
||||
, bool compact_mode
|
||||
, int block_size)
|
||||
{
|
||||
// make sure the block_size is an even power of 2
|
||||
#ifndef NDEBUG
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
if (block_size & (1 << i))
|
||||
{
|
||||
assert((block_size & ~(1 << i)) == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
assert(!save_path.empty());
|
||||
torrent_info ti(metadata);
|
||||
|
||||
|
@ -992,7 +1006,7 @@ namespace libtorrent
|
|||
// the thread
|
||||
boost::shared_ptr<torrent> torrent_ptr(
|
||||
new torrent(m_impl, metadata, save_path, m_impl.m_listen_interface
|
||||
, compact_mode));
|
||||
, compact_mode, block_size));
|
||||
|
||||
detail::piece_checker_data d;
|
||||
d.torrent_ptr = torrent_ptr;
|
||||
|
@ -1014,8 +1028,21 @@ namespace libtorrent
|
|||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, entry const&
|
||||
, bool compact_mode)
|
||||
, bool compact_mode
|
||||
, int block_size)
|
||||
{
|
||||
// make sure the block_size is an even power of 2
|
||||
#ifndef NDEBUG
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
if (block_size & (1 << i))
|
||||
{
|
||||
assert((block_size & ~(1 << i)) == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: support resume data in this case
|
||||
assert(!save_path.empty());
|
||||
{
|
||||
|
@ -1043,7 +1070,7 @@ namespace libtorrent
|
|||
// the thread
|
||||
boost::shared_ptr<torrent> torrent_ptr(
|
||||
new torrent(m_impl, tracker_url, info_hash, save_path
|
||||
, m_impl.m_listen_interface, compact_mode));
|
||||
, m_impl.m_listen_interface, compact_mode, block_size));
|
||||
|
||||
m_impl.m_torrents.insert(
|
||||
std::make_pair(info_hash, torrent_ptr)).first;
|
||||
|
@ -1289,85 +1316,83 @@ namespace libtorrent
|
|||
tmp_pieces.push_back(index);
|
||||
}
|
||||
|
||||
|
||||
int num_blocks_per_piece = (int)rd["blocks per piece"].integer();
|
||||
if (num_blocks_per_piece != info.piece_length() / torrent_ptr->block_size())
|
||||
{
|
||||
error = "invalid number of blocks per piece ("
|
||||
+ boost::lexical_cast<std::string>(num_blocks_per_piece) + ")";
|
||||
return;
|
||||
}
|
||||
|
||||
// the unfinished pieces
|
||||
|
||||
entry::list_type& unfinished = rd["unfinished"].list();
|
||||
|
||||
// only bother to check the partial pieces if we have the same block size
|
||||
// as in the fast resume data. If the blocksize has changed, then throw
|
||||
// away all partial pieces.
|
||||
std::vector<piece_picker::downloading_piece> tmp_unfinished;
|
||||
tmp_unfinished.reserve(unfinished.size());
|
||||
for (entry::list_type::iterator i = unfinished.begin();
|
||||
i != unfinished.end(); ++i)
|
||||
int num_blocks_per_piece = (int)rd["blocks per piece"].integer();
|
||||
if (num_blocks_per_piece == info.piece_length() / torrent_ptr->block_size())
|
||||
{
|
||||
piece_picker::downloading_piece p;
|
||||
// the unfinished pieces
|
||||
|
||||
p.index = (int)(*i)["piece"].integer();
|
||||
if (p.index < 0 || p.index >= info.num_pieces())
|
||||
{
|
||||
error = "invalid piece index in unfinished piece list (index: "
|
||||
+ boost::lexical_cast<std::string>(p.index) + " size: "
|
||||
+ boost::lexical_cast<std::string>(info.num_pieces()) + ")";
|
||||
return;
|
||||
}
|
||||
entry::list_type& unfinished = rd["unfinished"].list();
|
||||
|
||||
const std::string& bitmask = (*i)["bitmask"].string();
|
||||
|
||||
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
||||
if ((int)bitmask.size() != num_bitmask_bytes)
|
||||
tmp_unfinished.reserve(unfinished.size());
|
||||
for (entry::list_type::iterator i = unfinished.begin();
|
||||
i != unfinished.end(); ++i)
|
||||
{
|
||||
error = "invalid size of bitmask (" + boost::lexical_cast<std::string>(bitmask.size()) + ")";
|
||||
return;
|
||||
}
|
||||
for (int j = 0; j < num_bitmask_bytes; ++j)
|
||||
{
|
||||
unsigned char bits = bitmask[j];
|
||||
for (int k = 0; k < 8; ++k)
|
||||
piece_picker::downloading_piece p;
|
||||
|
||||
p.index = (int)(*i)["piece"].integer();
|
||||
if (p.index < 0 || p.index >= info.num_pieces())
|
||||
{
|
||||
const int bit = j * 8 + k;
|
||||
if (bits & (1 << k))
|
||||
p.finished_blocks[bit] = true;
|
||||
error = "invalid piece index in unfinished piece list (index: "
|
||||
+ boost::lexical_cast<std::string>(p.index) + " size: "
|
||||
+ boost::lexical_cast<std::string>(info.num_pieces()) + ")";
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& bitmask = (*i)["bitmask"].string();
|
||||
|
||||
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
||||
if ((int)bitmask.size() != num_bitmask_bytes)
|
||||
{
|
||||
error = "invalid size of bitmask (" + boost::lexical_cast<std::string>(bitmask.size()) + ")";
|
||||
return;
|
||||
}
|
||||
for (int j = 0; j < num_bitmask_bytes; ++j)
|
||||
{
|
||||
unsigned char bits = bitmask[j];
|
||||
for (int k = 0; k < 8; ++k)
|
||||
{
|
||||
const int bit = j * 8 + k;
|
||||
if (bits & (1 << k))
|
||||
p.finished_blocks[bit] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.finished_blocks.count() == 0) continue;
|
||||
|
||||
std::vector<int>::iterator slot_iter
|
||||
= std::find(tmp_pieces.begin(), tmp_pieces.end(), p.index);
|
||||
if (slot_iter == tmp_pieces.end())
|
||||
{
|
||||
// this piece is marked as unfinished
|
||||
// but doesn't have any storage
|
||||
error = "piece " + boost::lexical_cast<std::string>(p.index) + " is "
|
||||
"marked as unfinished, but doesn't have any storage";
|
||||
return;
|
||||
}
|
||||
|
||||
assert(*slot_iter == p.index);
|
||||
int slot_index = static_cast<int>(slot_iter - tmp_pieces.begin());
|
||||
unsigned long adler
|
||||
= torrent_ptr->filesystem().piece_crc(
|
||||
slot_index
|
||||
, torrent_ptr->block_size()
|
||||
, p.finished_blocks);
|
||||
|
||||
const entry& ad = (*i)["adler32"];
|
||||
|
||||
// crc's didn't match, don't use the resume data
|
||||
if (ad.integer() != adler)
|
||||
{
|
||||
error = "checksum mismatch on piece " + boost::lexical_cast<std::string>(p.index);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_unfinished.push_back(p);
|
||||
}
|
||||
|
||||
if (p.finished_blocks.count() == 0) continue;
|
||||
|
||||
std::vector<int>::iterator slot_iter
|
||||
= std::find(tmp_pieces.begin(), tmp_pieces.end(), p.index);
|
||||
if (slot_iter == tmp_pieces.end())
|
||||
{
|
||||
// this piece is marked as unfinished
|
||||
// but doesn't have any storage
|
||||
error = "piece " + boost::lexical_cast<std::string>(p.index) + " is "
|
||||
"marked as unfinished, but doesn't have any storage";
|
||||
return;
|
||||
}
|
||||
|
||||
assert(*slot_iter == p.index);
|
||||
int slot_index = static_cast<int>(slot_iter - tmp_pieces.begin());
|
||||
unsigned long adler
|
||||
= torrent_ptr->filesystem().piece_crc(
|
||||
slot_index
|
||||
, torrent_ptr->block_size()
|
||||
, p.finished_blocks);
|
||||
|
||||
const entry& ad = (*i)["adler32"];
|
||||
|
||||
// crc's didn't match, don't use the resume data
|
||||
if (ad.integer() != adler)
|
||||
{
|
||||
error = "checksum mismatch on piece " + boost::lexical_cast<std::string>(p.index);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_unfinished.push_back(p);
|
||||
}
|
||||
|
||||
// verify file sizes
|
||||
|
|
|
@ -88,9 +88,9 @@ namespace
|
|||
, tracker_failed_max = 5
|
||||
};
|
||||
|
||||
int calculate_block_size(const torrent_info& i)
|
||||
int calculate_block_size(const torrent_info& i, int default_block_size)
|
||||
{
|
||||
const int default_block_size = 16 * 1024;
|
||||
if (default_block_size < 1024) default_block_size = 1024;
|
||||
|
||||
// if pieces are too small, adjust the block size
|
||||
if (i.piece_length() < default_block_size)
|
||||
|
@ -151,7 +151,8 @@ namespace libtorrent
|
|||
, entry const& metadata
|
||||
, boost::filesystem::path const& save_path
|
||||
, address const& net_interface
|
||||
, bool compact_mode)
|
||||
, bool compact_mode
|
||||
, int block_size)
|
||||
: m_torrent_file(metadata)
|
||||
, m_abort(false)
|
||||
, m_paused(false)
|
||||
|
@ -183,6 +184,7 @@ namespace libtorrent
|
|||
, m_compact_mode(compact_mode)
|
||||
, m_metadata_progress(0)
|
||||
, m_metadata_size(0)
|
||||
, m_default_block_size(block_size)
|
||||
{
|
||||
m_uploads_quota.min = 2;
|
||||
m_connections_quota.min = 2;
|
||||
|
@ -203,7 +205,8 @@ namespace libtorrent
|
|||
, sha1_hash const& info_hash
|
||||
, boost::filesystem::path const& save_path
|
||||
, address const& net_interface
|
||||
, bool compact_mode)
|
||||
, bool compact_mode
|
||||
, int block_size)
|
||||
: m_torrent_file(info_hash)
|
||||
, m_abort(false)
|
||||
, m_paused(false)
|
||||
|
@ -234,6 +237,7 @@ namespace libtorrent
|
|||
, m_compact_mode(compact_mode)
|
||||
, m_metadata_progress(0)
|
||||
, m_metadata_size(0)
|
||||
, m_default_block_size(block_size)
|
||||
{
|
||||
m_uploads_quota.min = 2;
|
||||
m_connections_quota.min = 2;
|
||||
|
@ -263,7 +267,7 @@ namespace libtorrent
|
|||
|
||||
m_have_pieces.resize(m_torrent_file.num_pieces(), false);
|
||||
m_storage = std::auto_ptr<piece_manager>(new piece_manager(m_torrent_file, m_save_path));
|
||||
m_block_size = calculate_block_size(m_torrent_file);
|
||||
m_block_size = calculate_block_size(m_torrent_file, m_default_block_size);
|
||||
m_picker = std::auto_ptr<piece_picker>(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)));
|
||||
|
|
|
@ -149,7 +149,7 @@ namespace libtorrent
|
|||
|
||||
void torrent_info::set_piece_size(int size)
|
||||
{
|
||||
// make sure the size is an even 2 exponential
|
||||
// make sure the size is an even power of 2
|
||||
#ifndef NDEBUG
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue