forked from premiere/premiere-libtorrent
*** empty log message ***
This commit is contained in:
parent
3033f16f47
commit
97b387b196
|
@ -58,10 +58,14 @@
|
||||||
<li><a class="reference" href="#simple-client" id="id34" name="id34">simple client</a></li>
|
<li><a class="reference" href="#simple-client" id="id34" name="id34">simple client</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li><a class="reference" href="#fast-resume" id="id35" name="id35">fast resume</a><ul>
|
||||||
|
<li><a class="reference" href="#file-format" id="id36" name="id36">file format</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference" href="#feedback" id="id35" name="id35">Feedback</a></li>
|
</ul>
|
||||||
<li><a class="reference" href="#aknowledgements" id="id36" name="id36">Aknowledgements</a></li>
|
</li>
|
||||||
|
<li><a class="reference" href="#feedback" id="id37" name="id37">Feedback</a></li>
|
||||||
|
<li><a class="reference" href="#aknowledgements" id="id38" name="id38">Aknowledgements</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="introduction">
|
<div class="section" id="introduction">
|
||||||
|
@ -94,13 +98,14 @@ thread-safe library interface. (i.e. There's no way for the user to cause a dead
|
||||||
<li>piece-wise file allocation</li>
|
<li>piece-wise file allocation</li>
|
||||||
<li>tries to maintain a 1:1 share ratio between all peers but also shifts free
|
<li>tries to maintain a 1:1 share ratio between all peers but also shifts free
|
||||||
download to peers as free upload. To maintain a global 1:1 ratio.</li>
|
download to peers as free upload. To maintain a global 1:1 ratio.</li>
|
||||||
|
<li>fast resume support, a way to get rid of the costly piece check at the start
|
||||||
|
of a resumed torrent. Saves the storage state in a separate fast-resume file.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p>Functions that are yet to be implemented:</p>
|
<p>Functions that are yet to be implemented:</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li>choke/unchoke policy for seed-mode</li>
|
<li>choke/unchoke policy for seed-mode</li>
|
||||||
<li>fast resume</li>
|
|
||||||
<li>number of connections limit</li>
|
<li>number of connections limit</li>
|
||||||
<li>better handling of peers that send bad data</li>
|
<li>better handling of peers that send bad data</li>
|
||||||
<li>ip-filters</li>
|
<li>ip-filters</li>
|
||||||
|
@ -170,6 +175,11 @@ class session: public boost::noncopyable
|
||||||
session(int listen_port);
|
session(int listen_port);
|
||||||
|
|
||||||
torrent_handle add_torrent(const torrent_info& t, const std::string& save_path);
|
torrent_handle add_torrent(const torrent_info& t, const std::string& save_path);
|
||||||
|
torrent_handle add_torrent(
|
||||||
|
const torrent_info& t
|
||||||
|
, const std::string& save_path
|
||||||
|
, const std::vector<char>& resume_data);
|
||||||
|
|
||||||
void remove_torrent(const torrent_handle& h);
|
void remove_torrent(const torrent_handle& h);
|
||||||
|
|
||||||
void set_http_settings(const http_settings& settings);
|
void set_http_settings(const http_settings& settings);
|
||||||
|
@ -187,6 +197,9 @@ object representing the information found in the torrent file and the path where
|
||||||
want to save the files. The <tt class="literal"><span class="pre">save_path</span></tt> will be prepended to the directory-
|
want to save the files. The <tt class="literal"><span class="pre">save_path</span></tt> will be prepended to the directory-
|
||||||
structure in the torrent-file. <tt class="literal"><span class="pre">add_torrent</span></tt> will throw <tt class="literal"><span class="pre">duplicate_torrent</span></tt> exception
|
structure in the torrent-file. <tt class="literal"><span class="pre">add_torrent</span></tt> will throw <tt class="literal"><span class="pre">duplicate_torrent</span></tt> exception
|
||||||
if the torrent already exists in the session.</p>
|
if the torrent already exists in the session.</p>
|
||||||
|
<p>The optional last parameter, <tt class="literal"><span class="pre">resume_data</span></tt> can be given if up to date fast-resume data
|
||||||
|
is available. The fast-resume data can be acquired from a running torrent by calling
|
||||||
|
<tt class="literal"><span class="pre">torrent_handle::write_resume_data()</span></tt>. See <a class="reference" href="#fast-resume">fast resume</a>.</p>
|
||||||
<p><tt class="literal"><span class="pre">remove_torrent()</span></tt> will close all peer connections associated with the torrent and tell
|
<p><tt class="literal"><span class="pre">remove_torrent()</span></tt> will close all peer connections associated with the torrent and tell
|
||||||
the tracker that we've stopped participating in the swarm.</p>
|
the tracker that we've stopped participating in the swarm.</p>
|
||||||
<p>If the torrent you are trying to add already exists in the session (is either queued
|
<p>If the torrent you are trying to add already exists in the session (is either queued
|
||||||
|
@ -506,6 +519,8 @@ struct torrent_handle
|
||||||
const torrent_info& get_torrent_info();
|
const torrent_info& get_torrent_info();
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
|
|
||||||
|
void write_resume_data(std::vector<char>& data);
|
||||||
|
|
||||||
boost::filsystem::path save_path() const;
|
boost::filsystem::path save_path() const;
|
||||||
|
|
||||||
void set_max_uploads(int max_uploads);
|
void set_max_uploads(int max_uploads);
|
||||||
|
@ -525,10 +540,12 @@ was started.</p>
|
||||||
<p><tt class="literal"><span class="pre">info_hash()</span></tt> returns the info hash for the torrent.</p>
|
<p><tt class="literal"><span class="pre">info_hash()</span></tt> returns the info hash for the torrent.</p>
|
||||||
<p><tt class="literal"><span class="pre">set_max_uploads()</span></tt> sets the maximum number of peers that's unchoked at the same time on this
|
<p><tt class="literal"><span class="pre">set_max_uploads()</span></tt> sets the maximum number of peers that's unchoked at the same time on this
|
||||||
torrent. If you set this to -1, there will be no limit.</p>
|
torrent. If you set this to -1, there will be no limit.</p>
|
||||||
|
<p><tt class="literal"><span class="pre">write_resume_data()</span></tt> takes a non-const reference to a char-vector, that vector will be filled
|
||||||
|
with the fast-resume data. For more information about hpw fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>.</p>
|
||||||
<div class="section" id="status">
|
<div class="section" id="status">
|
||||||
<h3><a class="toc-backref" href="#id15" name="status">status()</a></h3>
|
<h3><a class="toc-backref" href="#id15" name="status">status()</a></h3>
|
||||||
<p><tt class="literal"><span class="pre">status()</span></tt> will return a structure with information about the status of this
|
<p><tt class="literal"><span class="pre">status()</span></tt> will return a structure with information about the status of this
|
||||||
torrent. If the <tt class="literal"><span class="pre">torrent_handle</span></tt> is invalid, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt> exception.
|
torrent. If the <a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, it will throw <a class="reference" href="#invalid-handle">invalid_handle</a> exception.
|
||||||
It contains the following fields:</p>
|
It contains the following fields:</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
struct torrent_status
|
struct torrent_status
|
||||||
|
@ -604,7 +621,7 @@ data), these counters ignore any protocol overhead.</p>
|
||||||
the pieces we don't have.</p>
|
the pieces we don't have.</p>
|
||||||
<p><tt class="literal"><span class="pre">download_rate</span></tt> and <tt class="literal"><span class="pre">upload_rate</span></tt> are the total rates for all peers for this
|
<p><tt class="literal"><span class="pre">download_rate</span></tt> and <tt class="literal"><span class="pre">upload_rate</span></tt> are the total rates for all peers for this
|
||||||
torrent. These will usually have better precision than summing the rates from
|
torrent. These will usually have better precision than summing the rates from
|
||||||
all peers.</p>
|
all peers. The rates are given as the number of bytes per second.</p>
|
||||||
<p><tt class="literal"><span class="pre">total_done</span></tt> is the total number of bytes of the file(s) that we have.</p>
|
<p><tt class="literal"><span class="pre">total_done</span></tt> is the total number of bytes of the file(s) that we have.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="get-download-queue">
|
<div class="section" id="get-download-queue">
|
||||||
|
@ -643,7 +660,7 @@ may pass then.</p>
|
||||||
<h3><a class="toc-backref" href="#id17" name="get-peer-info">get_peer_info()</a></h3>
|
<h3><a class="toc-backref" href="#id17" name="get-peer-info">get_peer_info()</a></h3>
|
||||||
<p><tt class="literal"><span class="pre">get_peer_info()</span></tt> takes a reference to a vector that will be cleared and filled
|
<p><tt class="literal"><span class="pre">get_peer_info()</span></tt> takes a reference to a vector that will be cleared and filled
|
||||||
with one entry for each peer connected to this torrent, given the handle is valid. If the
|
with one entry for each peer connected to this torrent, given the handle is valid. If the
|
||||||
<tt class="literal"><span class="pre">torrent_handle</span></tt> is invalid, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt> exception. Each entry in
|
<a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt> exception. Each entry in
|
||||||
the vector contains information about that particular peer. It contains the following
|
the vector contains information about that particular peer. It contains the following
|
||||||
fields:</p>
|
fields:</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
|
@ -717,8 +734,8 @@ the total number of bytes in this block.</p>
|
||||||
<div class="section" id="get-torrent-info">
|
<div class="section" id="get-torrent-info">
|
||||||
<h3><a class="toc-backref" href="#id18" name="get-torrent-info">get_torrent_info()</a></h3>
|
<h3><a class="toc-backref" href="#id18" name="get-torrent-info">get_torrent_info()</a></h3>
|
||||||
<p>Returns a const reference to the <tt class="literal"><span class="pre">torrent_info</span></tt> object associated with this torrent.
|
<p>Returns a const reference to the <tt class="literal"><span class="pre">torrent_info</span></tt> object associated with this torrent.
|
||||||
This reference is valid as long as the <tt class="literal"><span class="pre">torrent_handle</span></tt> is valid, no longer. If the
|
This reference is valid as long as the <a class="reference" href="#torrent-handle">torrent_handle</a> is valid, no longer. If the
|
||||||
<tt class="literal"><span class="pre">torrent_handle</span></tt> is invalid, <tt class="literal"><span class="pre">invalid_handle</span></tt> exception will be thrown.</p>
|
<a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, <a class="reference" href="#invalid-handle">invalid_handle</a> exception will be thrown.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="is-valid">
|
<div class="section" id="is-valid">
|
||||||
<h3><a class="toc-backref" href="#id19" name="is-valid">is_valid()</a></h3>
|
<h3><a class="toc-backref" href="#id19" name="is-valid">is_valid()</a></h3>
|
||||||
|
@ -922,7 +939,7 @@ public:
|
||||||
here's a complete list with description.</p>
|
here's a complete list with description.</p>
|
||||||
<div class="section" id="invalid-handle">
|
<div class="section" id="invalid-handle">
|
||||||
<h3><a class="toc-backref" href="#id27" name="invalid-handle">invalid_handle</a></h3>
|
<h3><a class="toc-backref" href="#id27" name="invalid-handle">invalid_handle</a></h3>
|
||||||
<p>This exception is thrown when querying information from a <tt class="literal"><span class="pre">torrent_handle</span></tt> that hasn't
|
<p>This exception is thrown when querying information from a <a class="reference" href="#torrent-handle">torrent_handle</a> that hasn't
|
||||||
been initialized or that has become invalid.</p>
|
been initialized or that has become invalid.</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
struct invalid_handle: std::exception
|
struct invalid_handle: std::exception
|
||||||
|
@ -1093,14 +1110,49 @@ int main(int argc, char* argv[])
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section" id="fast-resume">
|
||||||
|
<h2><a class="toc-backref" href="#id35" name="fast-resume">fast resume</a></h2>
|
||||||
|
<p>The fast resume mechanism is a way to remember which pieces are downloaded and where they
|
||||||
|
are put between sessions. You can generate fast resume data by calling
|
||||||
|
<tt class="literal"><span class="pre">torrent_handle::write_resume_data()</span></tt> on <a class="reference" href="#torrent-handle">torrent_handle</a>. You can then save this data
|
||||||
|
to disk and use it when resuming the torrent. libtorrent will not check the piece hashes
|
||||||
|
then, and rely on the information given in the fast-resume data. The fast-resume data
|
||||||
|
also contains information about which bocks in the unfinished pieces were downloaded, so
|
||||||
|
it will not have to start from scratch on the partially downloaded pieces.</p>
|
||||||
|
<p>To use the fast-resume data you simply give it to <tt class="literal"><span class="pre">session::add_torrent()</span></tt>, and it
|
||||||
|
will skip the time consuming checks. It may have to do the checking anyway, if the
|
||||||
|
fast-resume data is corrupt or doesn't fit the storage for that torrent, then it will
|
||||||
|
not trust the fast-resume data and just do the checking.</p>
|
||||||
|
<div class="section" id="file-format">
|
||||||
|
<h3><a class="toc-backref" href="#id36" name="file-format">file format</a></h3>
|
||||||
|
<p>The format of the fast-resume data is as follows, given that all
|
||||||
|
4-byte integers are stored as big-endian:</p>
|
||||||
|
<pre class="literal-block">
|
||||||
|
20 bytes, the info_hash for the torrent
|
||||||
|
4 bytes, the number of allocated slots in the storage
|
||||||
|
for each slot
|
||||||
|
4 bytes, piece index in this slot,
|
||||||
|
-1 means there's no storage for the slot
|
||||||
|
-2 means there's no piece at this slot, it's free
|
||||||
|
4 bytes, the number of blocks per piece.
|
||||||
|
this must be piece_size / 16k or 1 if piece_size is < 16k
|
||||||
|
and can be 128 at max.
|
||||||
|
4 bytes, the number of unfinished pieces
|
||||||
|
for each unfinished piece
|
||||||
|
4 bytes, index of the unfinished piece
|
||||||
|
blocks_per_piece / 32 bytes, the bitmask describing which
|
||||||
|
blocks are finished in this piece.
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="feedback">
|
<div class="section" id="feedback">
|
||||||
<h1><a class="toc-backref" href="#id35" name="feedback">Feedback</a></h1>
|
<h1><a class="toc-backref" href="#id37" name="feedback">Feedback</a></h1>
|
||||||
<p>There's a <a class="reference" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>.</p>
|
<p>There's a <a class="reference" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>.</p>
|
||||||
<p>You can usually find me as hydri in <tt class="literal"><span class="pre">#btports</span> <span class="pre">@</span> <span class="pre">irc.freenode.net</span></tt>.</p>
|
<p>You can usually find me as hydri in <tt class="literal"><span class="pre">#btports</span> <span class="pre">@</span> <span class="pre">irc.freenode.net</span></tt>.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="aknowledgements">
|
<div class="section" id="aknowledgements">
|
||||||
<h1><a class="toc-backref" href="#id36" name="aknowledgements">Aknowledgements</a></h1>
|
<h1><a class="toc-backref" href="#id38" name="aknowledgements">Aknowledgements</a></h1>
|
||||||
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
||||||
<p>Contributions by Magnus Jonsson</p>
|
<p>Contributions by Magnus Jonsson</p>
|
||||||
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
||||||
|
|
|
@ -43,6 +43,8 @@ The current state includes the following features:
|
||||||
* piece-wise file allocation
|
* piece-wise file allocation
|
||||||
* tries to maintain a 1:1 share ratio between all peers but also shifts free
|
* tries to maintain a 1:1 share ratio between all peers but also shifts free
|
||||||
download to peers as free upload. To maintain a global 1:1 ratio.
|
download to peers as free upload. To maintain a global 1:1 ratio.
|
||||||
|
* fast resume support, a way to get rid of the costly piece check at the start
|
||||||
|
of a resumed torrent. Saves the storage state in a separate fast-resume file.
|
||||||
|
|
||||||
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
||||||
.. _Azureus: http://azureus.sourceforge.net
|
.. _Azureus: http://azureus.sourceforge.net
|
||||||
|
@ -50,7 +52,6 @@ __ http://home.elp.rr.com/tur/multitracker-spec.txt
|
||||||
Functions that are yet to be implemented:
|
Functions that are yet to be implemented:
|
||||||
|
|
||||||
* choke/unchoke policy for seed-mode
|
* choke/unchoke policy for seed-mode
|
||||||
* fast resume
|
|
||||||
* number of connections limit
|
* number of connections limit
|
||||||
* better handling of peers that send bad data
|
* better handling of peers that send bad data
|
||||||
* ip-filters
|
* ip-filters
|
||||||
|
@ -134,6 +135,11 @@ The ``session`` class has the following synopsis::
|
||||||
session(int listen_port);
|
session(int listen_port);
|
||||||
|
|
||||||
torrent_handle add_torrent(const torrent_info& t, const std::string& save_path);
|
torrent_handle add_torrent(const torrent_info& t, const std::string& save_path);
|
||||||
|
torrent_handle add_torrent(
|
||||||
|
const torrent_info& t
|
||||||
|
, const std::string& save_path
|
||||||
|
, const std::vector<char>& resume_data);
|
||||||
|
|
||||||
void remove_torrent(const torrent_handle& h);
|
void remove_torrent(const torrent_handle& h);
|
||||||
|
|
||||||
void set_http_settings(const http_settings& settings);
|
void set_http_settings(const http_settings& settings);
|
||||||
|
@ -152,6 +158,10 @@ want to save the files. The ``save_path`` will be prepended to the directory-
|
||||||
structure in the torrent-file. ``add_torrent`` will throw ``duplicate_torrent`` exception
|
structure in the torrent-file. ``add_torrent`` will throw ``duplicate_torrent`` exception
|
||||||
if the torrent already exists in the session.
|
if the torrent already exists in the session.
|
||||||
|
|
||||||
|
The optional last parameter, ``resume_data`` can be given if up to date fast-resume data
|
||||||
|
is available. The fast-resume data can be acquired from a running torrent by calling
|
||||||
|
``torrent_handle::write_resume_data()``. See `fast resume`_.
|
||||||
|
|
||||||
``remove_torrent()`` will close all peer connections associated with the torrent and tell
|
``remove_torrent()`` will close all peer connections associated with the torrent and tell
|
||||||
the tracker that we've stopped participating in the swarm.
|
the tracker that we've stopped participating in the swarm.
|
||||||
|
|
||||||
|
@ -515,6 +525,8 @@ Its declaration looks like this::
|
||||||
const torrent_info& get_torrent_info();
|
const torrent_info& get_torrent_info();
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
|
|
||||||
|
void write_resume_data(std::vector<char>& data);
|
||||||
|
|
||||||
boost::filsystem::path save_path() const;
|
boost::filsystem::path save_path() const;
|
||||||
|
|
||||||
void set_max_uploads(int max_uploads);
|
void set_max_uploads(int max_uploads);
|
||||||
|
@ -538,11 +550,14 @@ was started.
|
||||||
``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this
|
``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this
|
||||||
torrent. If you set this to -1, there will be no limit.
|
torrent. If you set this to -1, there will be no limit.
|
||||||
|
|
||||||
|
``write_resume_data()`` takes a non-const reference to a char-vector, that vector will be filled
|
||||||
|
with the fast-resume data. For more information about hpw fast-resume works, see `fast resume`_.
|
||||||
|
|
||||||
status()
|
status()
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
``status()`` will return a structure with information about the status of this
|
``status()`` will return a structure with information about the status of this
|
||||||
torrent. If the ``torrent_handle`` is invalid, it will throw ``invalid_handle`` exception.
|
torrent. If the torrent_handle_ is invalid, it will throw invalid_handle_ exception.
|
||||||
It contains the following fields::
|
It contains the following fields::
|
||||||
|
|
||||||
struct torrent_status
|
struct torrent_status
|
||||||
|
@ -662,7 +677,7 @@ get_peer_info()
|
||||||
|
|
||||||
``get_peer_info()`` takes a reference to a vector that will be cleared and filled
|
``get_peer_info()`` takes a reference to a vector that will be cleared and filled
|
||||||
with one entry for each peer connected to this torrent, given the handle is valid. If the
|
with one entry for each peer connected to this torrent, given the handle is valid. If the
|
||||||
``torrent_handle`` is invalid, it will throw ``invalid_handle`` exception. Each entry in
|
torrent_handle_ is invalid, it will throw ``invalid_handle`` exception. Each entry in
|
||||||
the vector contains information about that particular peer. It contains the following
|
the vector contains information about that particular peer. It contains the following
|
||||||
fields::
|
fields::
|
||||||
|
|
||||||
|
@ -747,8 +762,8 @@ get_torrent_info()
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Returns a const reference to the ``torrent_info`` object associated with this torrent.
|
Returns a const reference to the ``torrent_info`` object associated with this torrent.
|
||||||
This reference is valid as long as the ``torrent_handle`` is valid, no longer. If the
|
This reference is valid as long as the torrent_handle_ is valid, no longer. If the
|
||||||
``torrent_handle`` is invalid, ``invalid_handle`` exception will be thrown.
|
torrent_handle_ is invalid, invalid_handle_ exception will be thrown.
|
||||||
|
|
||||||
|
|
||||||
is_valid()
|
is_valid()
|
||||||
|
@ -976,7 +991,7 @@ here's a complete list with description.
|
||||||
invalid_handle
|
invalid_handle
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
This exception is thrown when querying information from a ``torrent_handle`` that hasn't
|
This exception is thrown when querying information from a torrent_handle_ that hasn't
|
||||||
been initialized or that has become invalid.
|
been initialized or that has become invalid.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -1162,6 +1177,43 @@ This is a simple client. It doesn't have much output to keep it simple::
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fast resume
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The fast resume mechanism is a way to remember which pieces are downloaded and where they
|
||||||
|
are put between sessions. You can generate fast resume data by calling
|
||||||
|
``torrent_handle::write_resume_data()`` on torrent_handle_. You can then save this data
|
||||||
|
to disk and use it when resuming the torrent. libtorrent will not check the piece hashes
|
||||||
|
then, and rely on the information given in the fast-resume data. The fast-resume data
|
||||||
|
also contains information about which bocks in the unfinished pieces were downloaded, so
|
||||||
|
it will not have to start from scratch on the partially downloaded pieces.
|
||||||
|
|
||||||
|
To use the fast-resume data you simply give it to ``session::add_torrent()``, and it
|
||||||
|
will skip the time consuming checks. It may have to do the checking anyway, if the
|
||||||
|
fast-resume data is corrupt or doesn't fit the storage for that torrent, then it will
|
||||||
|
not trust the fast-resume data and just do the checking.
|
||||||
|
|
||||||
|
file format
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
The format of the fast-resume data is as follows, given that all
|
||||||
|
4-byte integers are stored as big-endian::
|
||||||
|
|
||||||
|
20 bytes, the info_hash for the torrent
|
||||||
|
4 bytes, the number of allocated slots in the storage
|
||||||
|
for each slot
|
||||||
|
4 bytes, piece index in this slot,
|
||||||
|
-1 means there's no storage for the slot
|
||||||
|
-2 means there's no piece at this slot, it's free
|
||||||
|
4 bytes, the number of blocks per piece.
|
||||||
|
this must be piece_size / 16k or 1 if piece_size is < 16k
|
||||||
|
and can be 128 at max.
|
||||||
|
4 bytes, the number of unfinished pieces
|
||||||
|
for each unfinished piece
|
||||||
|
4 bytes, index of the unfinished piece
|
||||||
|
blocks_per_piece / 32 bytes, the bitmask describing which
|
||||||
|
blocks are finished in this piece.
|
||||||
|
|
||||||
Feedback
|
Feedback
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace libtorrent
|
||||||
// reads an integer from a byte stream
|
// reads an integer from a byte stream
|
||||||
// in big endian byte order and converts
|
// in big endian byte order and converts
|
||||||
// it to native endianess
|
// it to native endianess
|
||||||
template<class InIt>
|
template <class InIt>
|
||||||
unsigned int read_uint(InIt& start)
|
unsigned int read_uint(InIt& start)
|
||||||
{
|
{
|
||||||
unsigned int val = 0;
|
unsigned int val = 0;
|
||||||
|
@ -90,15 +90,23 @@ namespace libtorrent
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InIt>
|
template <class InIt>
|
||||||
inline int read_int(InIt& start)
|
inline int read_int(InIt& start)
|
||||||
{
|
{
|
||||||
return static_cast<int>(read_uint(start));
|
return static_cast<int>(read_uint(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class InIt>
|
||||||
|
inline unsigned char read_uchar(InIt& start)
|
||||||
|
{
|
||||||
|
unsigned char ret = static_cast<unsigned char>(*start);
|
||||||
|
++start;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// reads an integer to a byte stream
|
// reads an integer to a byte stream
|
||||||
// and converts it from native endianess
|
// and converts it from native endianess
|
||||||
template<class OutIt>
|
template <class OutIt>
|
||||||
void write_uint(unsigned int val, OutIt& start)
|
void write_uint(unsigned int val, OutIt& start)
|
||||||
{
|
{
|
||||||
*start = static_cast<unsigned char>((val >> 24) & 0xff); ++start;
|
*start = static_cast<unsigned char>((val >> 24) & 0xff); ++start;
|
||||||
|
@ -107,10 +115,17 @@ namespace libtorrent
|
||||||
*start = static_cast<unsigned char>((val) & 0xff); ++start;
|
*start = static_cast<unsigned char>((val) & 0xff); ++start;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class OutIt>
|
template <class OutIt>
|
||||||
inline void write_int(int val, OutIt& start)
|
inline void write_int(int val, OutIt& start)
|
||||||
{
|
{
|
||||||
write_uint(reinterpret_cast<unsigned int&>(val), start);
|
write_uint(static_cast<unsigned int>(val), start);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OutIt>
|
||||||
|
inline void write_uchar(unsigned char val, OutIt& start)
|
||||||
|
{
|
||||||
|
*start = static_cast<char>(val);
|
||||||
|
++start;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace libtorrent
|
||||||
|
|
||||||
detail::session_impl* m_ses;
|
detail::session_impl* m_ses;
|
||||||
detail::checker_impl* m_chk;
|
detail::checker_impl* m_chk;
|
||||||
sha1_hash m_info_hash; // should be replaced with a torrent*?
|
sha1_hash m_info_hash;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -894,12 +894,16 @@ namespace libtorrent
|
||||||
|
|
||||||
const std::vector<char>& data = *rd;
|
const std::vector<char>& data = *rd;
|
||||||
|
|
||||||
if (data.size() < 3 * 4) return;
|
if (data.size() < 20 + 3 * 4) return;
|
||||||
std::vector<char>::const_iterator ptr = data.begin();
|
std::vector<char>::const_iterator ptr = data.begin();
|
||||||
|
|
||||||
|
sha1_hash info_hash;
|
||||||
|
for (int i = 0; i < 20; ++i) info_hash[i] = read_uchar(ptr);
|
||||||
|
if (info.info_hash() != info_hash) return;
|
||||||
|
|
||||||
int num_slots = detail::read_int(ptr);
|
int num_slots = detail::read_int(ptr);
|
||||||
if (num_slots < 0) return;
|
if (num_slots < 0) return;
|
||||||
if (data.size() < (3 + num_slots) * 4) return;
|
if (data.size() < 20 + (3 + num_slots) * 4) return;
|
||||||
|
|
||||||
tmp_pieces.reserve(num_slots);
|
tmp_pieces.reserve(num_slots);
|
||||||
for (int i = 0; i < num_slots; ++i)
|
for (int i = 0; i < num_slots; ++i)
|
||||||
|
@ -911,12 +915,12 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_blocks_per_piece = read_int(ptr);
|
int num_blocks_per_piece = read_int(ptr);
|
||||||
if (num_blocks_per_piece > 128 || num_blocks_per_piece < 0)
|
if (num_blocks_per_piece > 128 || num_blocks_per_piece < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int num_unfinished = read_int(ptr);
|
int num_unfinished = read_int(ptr);
|
||||||
if (num_unfinished < 0) return;
|
if (num_unfinished < 0) return;
|
||||||
if (data.size() != (1 + num_slots + 2 + num_unfinished * (num_blocks_per_piece / 32 + 1)) * 4)
|
if (data.size() != 20 + (1 + num_slots + 2 + num_unfinished * (num_blocks_per_piece / 32 + 1)) * 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp_unfinished.reserve(num_unfinished);
|
tmp_unfinished.reserve(num_unfinished);
|
||||||
|
|
|
@ -186,7 +186,13 @@ namespace libtorrent
|
||||||
|
|
||||||
// TODO: write file header
|
// TODO: write file header
|
||||||
// TODO: write modification-dates for all files
|
// TODO: write modification-dates for all files
|
||||||
// TODO: write info hash
|
|
||||||
|
for (sha1_hash::const_iterator i = m_info_hash.begin();
|
||||||
|
i != m_info_hash.end();
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
detail::write_uchar(*i, out);
|
||||||
|
}
|
||||||
|
|
||||||
// number of slots
|
// number of slots
|
||||||
int num_slots = piece_index.size();
|
int num_slots = piece_index.size();
|
||||||
|
|
Loading…
Reference in New Issue