regenerated html and added html files to the repo

This commit is contained in:
Arvid Norberg 2013-12-21 09:54:17 +00:00
parent 11a584991b
commit 90452a9bf3
22 changed files with 15021 additions and 8269 deletions

136
docs/base.css Normal file
View File

@ -0,0 +1,136 @@
/* Page template */
html>body { font-size: 13px; }
body { text-align: center; }
#container {
text-align: left;
width: 700px;
margin: 0 auto;
position: relative;
}
#headerNav {
}
#headerNav ul {
margin: 2px;
list-style: none;
font-family: Tahoma;
text-align: right;
text-transform: uppercase;
line-height: 1em;
}
#headerNav ul li {
display: inline;
border-left: solid 1px #ccc;
padding-left: 10px;
padding-right: 10px;
margin: 0;
font-size: 80%;
}
#headerNav ul li.first {
border: 0;
}
#headerNav ul li a {
border: none;
color: #666;
}
#headerNav ul li a:hover {
background: #eee;
}
#header {
height: 116px;
width: 695px;
background: url(../img/orange.png) #FDA72A no-repeat top left;
}
#header h1 {
margin: 0;
padding: 0;
float: right;
width: 536px;
height: 116px;
background: url(../img/logo.png);
}
#header h1 span, #header h2 { display: none; }
#footer {
clear: both;
width: 695px;
height: 49px;
background: #D3D3D3 url(../img/footer.png) no-repeat left top;
text-align: center;
margin-bottom: 1em;
}
#footer span {
line-height: 49px;
font-size: 88%;
text-align: center;
color: #777;
display: block;
}
#main {
font-family: Verdana;
line-height: 1.25em;
text-align: left;
margin-top: 10px;
}
/* Base elements */
* {margin: 0; padding: 0;}
body { font: 0.8125em Verdana, sans-serif;}
h1, h2, h3 {
font: 1.5em Georgia "Times New Roman", serif;
letter-spacing: 1px;
padding-bottom: 0.5em;
}
h1 { font-size: 180%; }
h2 { font-size: 130%; }
h3 { font-size: 100%; }
p {
font-size: 92%;
line-height: 1.7em;
}
a {
text-decoration: none;
color: #8D370A;
border-bottom: dotted 1px #8D370A;
}
a:hover {
border-bottom: solid 1px #8D370A;
background: #eee;
}
#librarySidebar {
float: left;
width: 150px;
}
#libraryBody {
border-left: solid 1px #eee;
padding-left: 10px;
margin-left: 158px;
margin-right: 10px;
}
ul, ol { line-height: 1.8em; }
ul { list-style: square; }
li { margin-left: 2.8em; font-size: 92%; }
p, ul, ol, img {margin-bottom: 1em;}

221
docs/hacking.html Normal file
View File

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>libtorrent hacking</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="libtorrent-hacking">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">libtorrent hacking</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#terminology" id="id1">terminology</a></li>
<li><a class="reference internal" href="#structure" id="id2">structure</a><ul>
<li><a class="reference internal" href="#session-impl" id="id3">session_impl</a></li>
<li><a class="reference internal" href="#session" id="id4">session</a></li>
<li><a class="reference internal" href="#torrent-handle" id="id5">torrent_handle</a></li>
<li><a class="reference internal" href="#torrent" id="id6">torrent</a></li>
<li><a class="reference internal" href="#peer-connection" id="id7">peer_connection</a></li>
<li><a class="reference internal" href="#policy" id="id8">policy</a></li>
<li><a class="reference internal" href="#piece-picker" id="id9">piece_picker</a></li>
<li><a class="reference internal" href="#torrent-info" id="id10">torrent_info</a></li>
</ul>
</li>
<li><a class="reference internal" href="#threads" id="id11">threads</a></li>
</ul>
</div>
<p>This describe some of the internals of libtorrent. If you're looking for
something to contribute, please take a look at the <a class="reference external" href="todo.html">todo list</a>.</p>
<div class="section" id="terminology">
<h1>terminology</h1>
<p>This section describes some of the terminology used throughout the
libtorrent source. Having a good understanding of some of these keywords
helps understanding what's going on.</p>
<p>A <em>piece</em> is a part of the data of a torrent that has a SHA-1 hash in
the .torrent file. Pieces are almost always a power of two in size, but not
necessarily. Each piece is plit up in <em>blocks</em>, which is a 16 kiB. A block
never spans two pieces. If a piece is smaller than 16 kiB or not divisible
by 16 kiB, there are blocks smaller than that.</p>
<p>16 kiB is a de-facto standard of the largest transfer unit in the bittorrent
protocol. Clients typically reject any request for larger pieces than this.</p>
<p>The <em>piece picker</em> is the part of a bittorrent client that is responsible for
the logic to determine which requests to send to peers. It doesn't actually
pick full pieces, but blocks (from pieces).</p>
<p>The file layout of a torrent is represented by <em>file storage</em> objects. This
class contains a list of all files in the torrent (in a well defined order),
the size of the pieces and implicitly the total size of the whole torrent and
number of pieces. The file storage determines the mapping from <em>pieces</em>
to <em>files</em>. This representation may be quite complex in order to keep it extremely
compact. This is useful to load very large torrents without exploding in memory
usage.</p>
<p>A <em>torrent</em> object represents all the state of swarm download. This includes
a piece picker, a list of peer connections, file storage (torrent file). One
important distiction is between a connected peer (<em>peer_connection</em>) and a peer
we just know about, and may have been connected to, and may connect to in the
future (<em>policy::peer</em>). The list of (not connected) peers may grow very large
if not limited (through tracker responses, DHT and peer exchange). This list
is typically limited to a few thousand peers.</p>
<p>The <em>policy</em> in libtorrent is somewhat poorly named. It was initially intended
to be a customization point where a client could define peer selection behavior
and unchoke logic. It didn't end up being though, and a more accurate name would
be peer_list. It really just maintains a potentially large list of known peers
for a swarm (not necessarily connected).</p>
</div>
<div class="section" id="structure">
<h1>structure</h1>
<p>This is the high level structure of libtorrent. Bold types are part of the public
interface:</p>
<pre class="literal-block">
+=========+ pimpl +-------------------+
| <strong>session</strong> | ---------&gt; | aux::session_impl |
+=========+ +-------------------+
m_torrents[] | |
+================+ | |
| <strong>torrent_handle</strong> | ------+ | |
+================+ | | |
| | | m_connections[]
| | |
| | +---------------------+
m_picker v v |
+--------------+ +---------+---------+-- . . |
| piece_picker | &lt;--+-| torrent | torrent | to |
+--------------+ | +---------+---------+-- . . |
m_torrent_file | | m_connections[] |
+==============+ | | |
| <strong>torrent_info</strong> | &lt;--+ v v
+==============+ | +-----------------+-----------------+-- . .
m_policy | | peer_connection | peer_connection | pe
+--------+ | +-----------------+-----------------+-- . .
| policy | &lt;--------+ | | m_socket
+--------+ | |
| m_peers[] | v
| | +-----------------------+
| | | socket_type (variant) |
v | +-----------------------+
+--------------+ |
| policy::peer | |
+--------------+ |
| policy::peer | |
+--------------+ m_peer_info|
| policy::peer | &lt;----------+
+--------------+
. .
+ - - - - - - -+
</pre>
<div class="section" id="session-impl">
<h2>session_impl</h2>
<p>This is the session state object, containing all session global information, such as:</p>
<blockquote>
<ul class="simple">
<li>the list of all torrents <tt class="docutils literal">m_torrent</tt>.</li>
<li>the list of all peer connections <tt class="docutils literal">m_connections</tt>.</li>
<li>the global rate limits <tt class="docutils literal">m_settings</tt>.</li>
<li>the DHT state <tt class="docutils literal">m_dht</tt>.</li>
<li>the port mapping state, <tt class="docutils literal">m_upnp</tt> and <tt class="docutils literal">m_natpmp</tt>.</li>
</ul>
</blockquote>
</div>
<div class="section" id="session">
<h2>session</h2>
<p>This is the public interface to the session. It implements pimpl (pointer to implementation)
in order to hide the internal representation of the <tt class="docutils literal">session_impl</tt> object from the user and
make binary compatibility simpler to maintain.</p>
</div>
<div class="section" id="torrent-handle">
<h2>torrent_handle</h2>
<p>This is the public interface to a <tt class="docutils literal">torrent</tt>. It holds a weak reference to the internal
<tt class="docutils literal">torrent</tt> object and manipulates it by sending messages to the network thread.</p>
</div>
<div class="section" id="torrent">
<h2>torrent</h2>
</div>
<div class="section" id="peer-connection">
<h2>peer_connection</h2>
</div>
<div class="section" id="policy">
<h2>policy</h2>
</div>
<div class="section" id="piece-picker">
<h2>piece_picker</h2>
</div>
<div class="section" id="torrent-info">
<h2>torrent_info</h2>
</div>
</div>
<div class="section" id="threads">
<h1>threads</h1>
<p>libtorrent starts 2 or 3 threads.</p>
<blockquote>
<ul class="simple">
<li>The first thread is the main thread that will sit
idle in a <tt class="docutils literal">kqueue()</tt> or <tt class="docutils literal">epoll</tt> call most of the time.
This thread runs the main loop that will send and receive
data on all connections.</li>
<li>The second thread is the disk I/O thread. All disk read and write operations
are passed to this thread and messages are passed back to the main thread when
the operation completes. The disk thread also verifies the piece hashes.</li>
<li>The third and forth threads are spawned by asio on systems that don't support
non-blocking host name resolution to simulate non-blocking getaddrinfo().</li>
</ul>
</blockquote>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

959
docs/manual-ref.html Normal file
View File

@ -0,0 +1,959 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>libtorrent API Documentation</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="libtorrent-api-documentation">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">libtorrent API Documentation</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#overview" id="id54">overview</a></li>
<li><a class="reference internal" href="#things-to-keep-in-mind" id="id55">things to keep in mind</a></li>
<li><a class="reference internal" href="#network-primitives" id="id56">network primitives</a></li>
<li><a class="reference internal" href="#exceptions" id="id57">exceptions</a></li>
<li><a class="reference internal" href="#magnet-links" id="id58">magnet links</a></li>
<li><a class="reference internal" href="#queuing" id="id59">queuing</a></li>
<li><a class="reference internal" href="#fast-resume" id="id60">fast resume</a></li>
<li><a class="reference internal" href="#storage-allocation" id="id61">storage allocation</a></li>
<li><a class="reference internal" href="#extensions" id="id62">extensions</a></li>
<li><a class="reference internal" href="#piece-picker" id="id63">piece picker</a></li>
<li><a class="reference internal" href="#ssl-torrents" id="id64">SSL torrents</a></li>
</ul>
</div>
<div class="section" id="overview">
<h1>overview</h1>
<p>The interface of libtorrent consists of a few classes. The main class is
the <tt class="docutils literal">session</tt>, it contains the main loop that serves all torrents.</p>
<p>The basic usage is as follows:</p>
<ul>
<li><p class="first">construct a <a class="reference external" href="reference-Session.html#session">session</a></p>
</li>
<li><p class="first">load <a class="reference external" href="reference-Session.html#session">session</a> state from settings file (see <a class="reference external" href="reference-Session.html#load_state()">load_state()</a>)</p>
</li>
<li><p class="first">start extensions (see <a class="reference external" href="reference-Core.html#add_extension()">add_extension()</a>).</p>
</li>
<li><p class="first">start DHT, LSD, UPnP, NAT-PMP etc (see <a class="reference external" href="reference-Session.html#start_dht()">start_dht()</a>, <a class="reference external" href="reference-Session.html#start_lsd()">start_lsd()</a>, <a class="reference external" href="reference-Session.html#start_upnp()">start_upnp()</a> and <a class="reference external" href="reference-Session.html#start_natpmp()">start_natpmp()</a>).</p>
</li>
<li><p class="first">parse .torrent-files and add them to the <a class="reference external" href="reference-Session.html#session">session</a> (see <a class="reference external" href="reference-Core.html#torrent_info">torrent_info</a>, <a class="reference external" href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <a class="reference external" href="reference-Session.html#add_torrent()">add_torrent()</a>)</p>
</li>
<li><p class="first">main loop (see <a class="reference external" href="reference-Session.html#session">session</a>)</p>
<blockquote>
<ul class="simple">
<li>poll for alerts (see <a class="reference external" href="reference-Session.html#wait_for_alert()">wait_for_alert()</a>, <a class="reference external" href="reference-Session.html#pop_alerts()">pop_alerts()</a>)</li>
<li>handle updates to torrents, (see <a class="reference external" href="reference-Alerts.html#state_update_alert">state_update_alert</a>).</li>
<li>handle other alerts, (see <a class="reference external" href="reference-Alerts.html#alert">alert</a>).</li>
<li>query the <a class="reference external" href="reference-Session.html#session">session</a> for information (see <a class="reference external" href="reference-Session.html#status()">session::status()</a>).</li>
<li>add and remove torrents from the <a class="reference external" href="reference-Session.html#session">session</a> (remove_torrent())</li>
</ul>
</blockquote>
</li>
<li><p class="first">save resume data for all torrent_handles (optional, see
<a class="reference external" href="reference-Core.html#save_resume_data()">save_resume_data()</a>)</p>
</li>
<li><p class="first">save <a class="reference external" href="reference-Session.html#session">session</a> state (see <a class="reference external" href="reference-Session.html#save_state()">save_state()</a>)</p>
</li>
<li><p class="first">destruct <a class="reference external" href="reference-Session.html#session">session</a> object</p>
</li>
</ul>
<p>Each class and function is described in this manual.</p>
<p>For a description on how to create torrent files, see <a class="reference external" href="reference-Create_Torrents.html#create_torrent">create_torrent</a>.</p>
</div>
<div class="section" id="things-to-keep-in-mind">
<h1>things to keep in mind</h1>
<p>A common problem developers are facing is torrents stopping without explanation.
Here is a description on which conditions libtorrent will stop your torrents,
how to find out about it and what to do about it.</p>
<p>Make sure to keep track of the paused state, the error state and the upload
mode of your torrents. By default, torrents are auto-managed, which means
libtorrent will pause them, unpause them, scrape them and take them out
of upload-mode automatically.</p>
<p>Whenever a torrent encounters a fatal error, it will be stopped, and the
<tt class="docutils literal"><span class="pre">torrent_status::error</span></tt> will describe the error that caused it. If a torrent
is auto managed, it is scraped periodically and paused or resumed based on
the number of downloaders per seed. This will effectively seed torrents that
are in the greatest need of seeds.</p>
<p>If a torrent hits a disk write error, it will be put into upload mode. This
means it will not download anything, but only upload. The assumption is that
the write error is caused by a full disk or write permission errors. If the
torrent is auto-managed, it will periodically be taken out of the upload
mode, trying to write things to the disk again. This means torrent will recover
from certain disk errors if the problem is resolved. If the torrent is not
auto managed, you have to call <a class="reference external" href="reference-Core.html#set_upload_mode()">set_upload_mode()</a> to turn
downloading back on again.</p>
</div>
<div class="section" id="network-primitives">
<h1>network primitives</h1>
<p>There are a few typedefs in the <tt class="docutils literal">libtorrent</tt> namespace which pulls
in network types from the <tt class="docutils literal">asio</tt> namespace. These are:</p>
<pre class="literal-block">
typedef asio::ip::address address;
typedef asio::ip::address_v4 address_v4;
typedef asio::ip::address_v6 address_v6;
using asio::ip::tcp;
using asio::ip::udp;
</pre>
<p>These are declared in the <tt class="docutils literal">&lt;libtorrent/socket.hpp&gt;</tt> header.</p>
<p>The <tt class="docutils literal">using</tt> statements will give easy access to:</p>
<pre class="literal-block">
tcp::endpoint
udp::endpoint
</pre>
<p>Which are the endpoint types used in libtorrent. An endpoint is an address
with an associated port.</p>
<p>For documentation on these types, please refer to the <a class="reference external" href="http://asio.sourceforge.net/asio-0.3.8/doc/asio/reference.html">asio documentation</a>.</p>
</div>
<div class="section" id="exceptions">
<h1>exceptions</h1>
<p>Many functions in libtorrent have two versions, one that throws exceptions on
errors and one that takes an <tt class="docutils literal">error_code</tt> reference which is filled with the
error code on errors.</p>
<p>There is one exception class that is used for errors in libtorrent, it is based
on boost.system's <tt class="docutils literal">error_code</tt> class to carry the error code.</p>
<p>For more information, see <a class="reference external" href="reference-Error_Codes.html#libtorrent_exception">libtorrent_exception</a> and <a class="reference external" href="reference-Error_Codes.html#error_code_enum">error_code_enum</a>.</p>
<div class="section" id="translating-error-codes">
<h2>translating error codes</h2>
<p>The error_code::message() function will typically return a localized error string,
for system errors. That is, errors that belong to the generic or system category.</p>
<p>Errors that belong to the libtorrent error category are not localized however, they
are only available in english. In order to translate libtorrent errors, compare the
error category of the <tt class="docutils literal">error_code</tt> object against <tt class="docutils literal"><span class="pre">libtorrent::get_libtorrent_category()</span></tt>,
and if matches, you know the error code refers to the list above. You can provide
your own mapping from error code to string, which is localized. In this case, you
cannot rely on <tt class="docutils literal"><span class="pre">error_code::message()</span></tt> to generate your strings.</p>
<p>The numeric values of the errors are part of the API and will stay the same, although
new error codes may be appended at the end.</p>
<p>Here's a simple example of how to translate error codes:</p>
<pre class="literal-block">
std::string error_code_to_string(boost::system::error_code const&amp; ec)
{
if (ec.category() != libtorrent::get_libtorrent_category())
{
return ec.message();
}
// the error is a libtorrent error
int code = ec.value();
static const char const* swedish[] =
{
&quot;inget fel&quot;,
&quot;en fil i torrenten kolliderar med en fil fran en annan torrent&quot;,
&quot;hash check misslyckades&quot;,
&quot;torrentfilen ar inte en dictionary&quot;,
&quot;'info'-nyckeln saknas eller ar korrupt i torrentfilen&quot;,
&quot;'info'-faltet ar inte en dictionary&quot;,
&quot;'piece length' faltet saknas eller ar korrupt i torrentfilen&quot;,
&quot;torrentfilen saknar namnfaltet&quot;,
&quot;ogiltigt namn i torrentfilen (kan vara en attack)&quot;,
// ... more strings here
};
// use the default error string in case we don't have it
// in our translated list
if (code &lt; 0 || code &gt;= sizeof(swedish)/sizeof(swedish[0]))
return ec.message();
return swedish[code];
}
</pre>
</div>
</div>
<div class="section" id="magnet-links">
<h1>magnet links</h1>
<p>Magnet links are URIs that includes an info-hash, a display name and optionally
a tracker url. The idea behind magnet links is that an end user can click on a
link in a browser and have it handled by a bittorrent application, to start a
download, without any .torrent file.</p>
<p>The format of the magnet URI is:</p>
<p><strong>magnet:?xt=urn:btih:</strong> <em>Base16 encoded info-hash</em> [ <strong>&amp;dn=</strong> <em>name of download</em> ] [ <strong>&amp;tr=</strong> <em>tracker URL</em> ]*</p>
</div>
<div class="section" id="queuing">
<h1>queuing</h1>
<p>libtorrent supports <em>queuing</em>. Which means it makes sure that a limited number of
torrents are being downloaded at any given time, and once a torrent is completely
downloaded, the next in line is started.</p>
<p>Torrents that are <em>auto managed</em> are subject to the queuing and the active torrents
limits. To make a torrent auto managed, set <tt class="docutils literal">auto_managed</tt> to true when adding the
torrent (see <a class="reference external" href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <a class="reference external" href="reference-Session.html#add_torrent()">add_torrent()</a>).</p>
<p>The limits of the number of downloading and seeding torrents are controlled via
<tt class="docutils literal">active_downloads</tt>, <tt class="docutils literal">active_seeds</tt> and <tt class="docutils literal">active_limit</tt> in <a class="reference external" href="reference-Settings.html#session_settings">session_settings</a>.
These limits takes non auto managed torrents into account as well. If there are
more non-auto managed torrents being downloaded than the <tt class="docutils literal">active_downloads</tt>
setting, any auto managed torrents will be queued until torrents are removed so
that the number drops below the limit.</p>
<p>The default values are 8 active downloads and 5 active seeds.</p>
<p>At a regular interval, torrents are checked if there needs to be any re-ordering of
which torrents are active and which are queued. This interval can be controlled via
<tt class="docutils literal">auto_manage_interval</tt> in <a class="reference external" href="reference-Settings.html#session_settings">session_settings</a>. It defaults to every 30 seconds.</p>
<p>For queuing to work, resume data needs to be saved and restored for all torrents.
See <a class="reference external" href="reference-Core.html#save_resume_data()">save_resume_data()</a>.</p>
<div class="section" id="downloading">
<h2>downloading</h2>
<p>Torrents that are currently being downloaded or incomplete (with bytes still to download)
are queued. The torrents in the front of the queue are started to be actively downloaded
and the rest are ordered with regards to their queue position. Any newly added torrent
is placed at the end of the queue. Once a torrent is removed or turns into a seed, its
queue position is -1 and all torrents that used to be after it in the queue, decreases their
position in order to fill the gap.</p>
<p>The queue positions are always in a sequence without any gaps.</p>
<p>Lower queue position means closer to the front of the queue, and will be started sooner than
torrents with higher queue positions.</p>
<p>To query a torrent for its position in the queue, or change its position, see:
<a class="reference external" href="reference-Core.html#queue_position()">queue_position()</a>, <a class="reference external" href="reference-Core.html#queue_position_up()">queue_position_up()</a>, <a class="reference external" href="reference-Core.html#queue_position_down()">queue_position_down()</a>, <a class="reference external" href="reference-Core.html#queue_position_top()">queue_position_top()</a> and <a class="reference external" href="reference-Core.html#queue_position_bottom()">queue_position_bottom()</a>.</p>
</div>
<div class="section" id="seeding">
<h2>seeding</h2>
<p>Auto managed seeding torrents are rotated, so that all of them are allocated a fair
amount of seeding. Torrents with fewer completed <em>seed cycles</em> are prioritized for
seeding. A seed cycle is completed when a torrent meets either the share ratio limit
(uploaded bytes / downloaded bytes), the share time ratio (time seeding / time
downloaing) or seed time limit (time seeded).</p>
<p>The relevant settings to control these limits are <tt class="docutils literal">share_ratio_limit</tt>,
<tt class="docutils literal">seed_time_ratio_limit</tt> and <tt class="docutils literal">seed_time_limit</tt> in <a class="reference external" href="reference-Settings.html#session_settings">session_settings</a>.</p>
</div>
</div>
<div class="section" id="fast-resume">
<h1>fast resume</h1>
<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 <a class="reference external" href="reference-Core.html#save_resume_data()">save_resume_data()</a> on <a class="reference external" href="reference-Core.html#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
blocks, 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 <a class="reference external" href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <a class="reference external" href="reference-Session.html#add_torrent()">add_torrent()</a>, 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">
<h2>file format</h2>
<p>The file format is a bencoded dictionary containing the following fields:</p>
<table border="1" class="docutils">
<colgroup>
<col width="30%" />
<col width="70%" />
</colgroup>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">file-format</span></tt></td>
<td>string: &quot;libtorrent resume file&quot;</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">file-version</span></tt></td>
<td>integer: 1</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">info-hash</span></tt></td>
<td>string, the info hash of the torrent this data is saved for.</td>
</tr>
<tr><td><tt class="docutils literal">blocks per piece</tt></td>
<td>integer, the number of blocks per piece. Must be: piece_size
/ (16 * 1024). Clamped to be within the range [1, 256]. It
is the number of blocks per (normal sized) piece. Usually
each block is 16 * 1024 bytes in size. But if piece size is
greater than 4 megabytes, the block size will increase.</td>
</tr>
<tr><td><tt class="docutils literal">pieces</tt></td>
<td>A string with piece flags, one character per piece.
Bit 1 means we have that piece.
Bit 2 means we have verified that this piece is correct.
This only applies when the torrent is in seed_mode.</td>
</tr>
<tr><td><tt class="docutils literal">slots</tt></td>
<td><p class="first">list of integers. The list maps slots to piece indices. It
tells which piece is on which slot. If piece index is -2 it
means it is free, that there's no piece there. If it is -1,
means the slot isn't allocated on disk yet. The pieces have
to meet the following requirement:</p>
<p class="last">If there's a slot at the position of the piece index,
the piece must be located in that slot.</p>
</td>
</tr>
<tr><td><tt class="docutils literal">total_uploaded</tt></td>
<td>integer. The number of bytes that have been uploaded in
total for this torrent.</td>
</tr>
<tr><td><tt class="docutils literal">total_downloaded</tt></td>
<td>integer. The number of bytes that have been downloaded in
total for this torrent.</td>
</tr>
<tr><td><tt class="docutils literal">active_time</tt></td>
<td>integer. The number of seconds this torrent has been active.
i.e. not paused.</td>
</tr>
<tr><td><tt class="docutils literal">seeding_time</tt></td>
<td>integer. The number of seconds this torrent has been active
and seeding.</td>
</tr>
<tr><td><tt class="docutils literal">num_seeds</tt></td>
<td>integer. An estimate of the number of seeds on this torrent
when the resume data was saved. This is scrape data or based
on the peer list if scrape data is unavailable.</td>
</tr>
<tr><td><tt class="docutils literal">num_downloaders</tt></td>
<td>integer. An estimate of the number of downloaders on this
torrent when the resume data was last saved. This is used as
an initial estimate until we acquire up-to-date scrape info.</td>
</tr>
<tr><td><tt class="docutils literal">upload_rate_limit</tt></td>
<td>integer. In case this torrent has a per-torrent upload rate
limit, this is that limit. In bytes per second.</td>
</tr>
<tr><td><tt class="docutils literal">download_rate_limit</tt></td>
<td>integer. The download rate limit for this torrent in case
one is set, in bytes per second.</td>
</tr>
<tr><td><tt class="docutils literal">max_connections</tt></td>
<td>integer. The max number of peer connections this torrent
may have, if a limit is set.</td>
</tr>
<tr><td><tt class="docutils literal">max_uploads</tt></td>
<td>integer. The max number of unchoked peers this torrent may
have, if a limit is set.</td>
</tr>
<tr><td><tt class="docutils literal">seed_mode</tt></td>
<td>integer. 1 if the torrent is in seed mode, 0 otherwise.</td>
</tr>
<tr><td><tt class="docutils literal">file_priority</tt></td>
<td>list of integers. One entry per file in the torrent. Each
entry is the priority of the file with the same index.</td>
</tr>
<tr><td><tt class="docutils literal">piece_priority</tt></td>
<td>string of bytes. Each byte is interpreted as an integer and
is the priority of that piece.</td>
</tr>
<tr><td><tt class="docutils literal">auto_managed</tt></td>
<td>integer. 1 if the torrent is auto managed, otherwise 0.</td>
</tr>
<tr><td><tt class="docutils literal">sequential_download</tt></td>
<td>integer. 1 if the torrent is in sequential download mode,
0 otherwise.</td>
</tr>
<tr><td><tt class="docutils literal">paused</tt></td>
<td>integer. 1 if the torrent is paused, 0 otherwise.</td>
</tr>
<tr><td><tt class="docutils literal">trackers</tt></td>
<td>list of lists of strings. The top level list lists all
tracker tiers. Each second level list is one tier of
trackers.</td>
</tr>
<tr><td><tt class="docutils literal">mapped_files</tt></td>
<td>list of strings. If any file in the torrent has been
renamed, this entry contains a list of all the filenames.
In the same order as in the torrent file.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">url-list</span></tt></td>
<td>list of strings. List of url-seed URLs used by this torrent.
The urls are expected to be properly encoded and not contain
any illegal url characters.</td>
</tr>
<tr><td><tt class="docutils literal">httpseeds</tt></td>
<td>list of strings. List of httpseed URLs used by this torrent.
The urls are expected to be properly encoded and not contain
any illegal url characters.</td>
</tr>
<tr><td><tt class="docutils literal">merkle tree</tt></td>
<td>string. In case this torrent is a merkle torrent, this is a
string containing the entire merkle tree, all nodes,
including the root and all leaves. The tree is not
necessarily complete, but complete enough to be able to send
any piece that we have, indicated by the have bitmask.</td>
</tr>
<tr><td><tt class="docutils literal">peers</tt></td>
<td><p class="first">list of dictionaries. Each dictionary has the following
layout:</p>
<table border="1" class="docutils">
<colgroup>
<col width="18%" />
<col width="82%" />
</colgroup>
<tbody valign="top">
<tr><td><tt class="docutils literal">ip</tt></td>
<td>string, the ip address of the peer. This is
not a binary representation of the ip
address, but the string representation. It
may be an IPv6 string or an IPv4 string.</td>
</tr>
<tr><td><tt class="docutils literal">port</tt></td>
<td>integer, the listen port of the peer</td>
</tr>
</tbody>
</table>
<p class="last">These are the local peers we were connected to when this
fast-resume data was saved.</p>
</td>
</tr>
<tr><td><tt class="docutils literal">unfinished</tt></td>
<td><p class="first">list of dictionaries. Each dictionary represents an
piece, and has the following layout:</p>
<table border="1" class="last docutils">
<colgroup>
<col width="23%" />
<col width="77%" />
</colgroup>
<tbody valign="top">
<tr><td><tt class="docutils literal">piece</tt></td>
<td>integer, the index of the piece this entry
refers to.</td>
</tr>
<tr><td><tt class="docutils literal">bitmask</tt></td>
<td>string, a binary bitmask representing the
blocks that have been downloaded in this
piece.</td>
</tr>
<tr><td><tt class="docutils literal">adler32</tt></td>
<td>The adler32 checksum of the data in the
blocks specified by <tt class="docutils literal">bitmask</tt>.</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr><td><tt class="docutils literal">file sizes</tt></td>
<td>list where each entry corresponds to a file in the file list
in the metadata. Each entry has a list of two values, the
first value is the size of the file in bytes, the second
is the time stamp when the last time someone wrote to it.
This information is used to compare with the files on disk.
All the files must match exactly this information in order
to consider the resume data as current. Otherwise a full
re-check is issued.</td>
</tr>
<tr><td><tt class="docutils literal">allocation</tt></td>
<td>The allocation mode for the storage. Can be either <tt class="docutils literal">full</tt>
or <tt class="docutils literal">compact</tt>. If this is full, the file sizes and
timestamps are disregarded. Pieces are assumed not to have
moved around even if the files have been modified after the
last resume data checkpoint.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="storage-allocation">
<h1>storage allocation</h1>
<p>There are two modes in which storage (files on disk) are allocated in libtorrent.</p>
<ol class="arabic simple">
<li>The traditional <em>full allocation</em> mode, where the entire files are filled up with
zeros before anything is downloaded. libtorrent will look for sparse files support
in the filesystem that is used for storage, and use sparse files or file system
zero fill support if present. This means that on NTFS, full allocation mode will
only allocate storage for the downloaded pieces.</li>
<li>The <em>sparse allocation</em>, sparse files are used, and pieces are downloaded directly
to where they belong. This is the recommended (and default) mode.</li>
</ol>
<p>In previous versions of libtorrent, a 3rd mode was supported, <em>compact allocation</em>.
Support for this is deprecated and will be removed in future versions of libtorrent.
It's still described in here for completeness.</p>
<p>The allocation mode is selected when a torrent is started. It is passed as an
argument to <a class="reference external" href="reference-Session.html#add_torrent()">session::add_torrent()</a> or <a class="reference external" href="reference-Session.html#async_add_torrent()">session::async_add_torrent()</a>.</p>
<p>The decision to use full allocation or compact allocation typically depends on whether
any files have priority 0 and if the filesystem supports sparse files.</p>
<div class="section" id="sparse-allocation">
<h2>sparse allocation</h2>
<p>On filesystems that supports sparse files, this allocation mode will only use
as much space as has been downloaded.</p>
<blockquote>
<ul class="simple">
<li>It does not require an allocation pass on startup.</li>
<li>It supports skipping files (setting prioirty to 0 to not download).</li>
<li>Fast resume data will remain valid even when file time stamps are out of date.</li>
</ul>
</blockquote>
</div>
<div class="section" id="full-allocation">
<h2>full allocation</h2>
<p>When a torrent is started in full allocation mode, the disk-io thread
will make sure that the entire storage is allocated, and fill any gaps with zeros.
This will be skipped if the filesystem supports sparse files or automatic zero filling.
It will of course still check for existing pieces and fast resume data. The main
drawbacks of this mode are:</p>
<blockquote>
<ul class="simple">
<li>It may take longer to start the torrent, since it will need to fill the files
with zeros on some systems. This delay is linearly dependent on the size of
the download.</li>
<li>The download may occupy unnecessary disk space between download sessions. In case
sparse files are not supported.</li>
<li>Disk caches usually perform extremely poorly with random access to large files
and may slow down a download considerably.</li>
</ul>
</blockquote>
<p>The benefits of this mode are:</p>
<blockquote>
<ul class="simple">
<li>Downloaded pieces are written directly to their final place in the files and the
total number of disk operations will be fewer and may also play nicer to
filesystems' file allocation, and reduce fragmentation.</li>
<li>No risk of a download failing because of a full disk during download. Unless
sparse files are being used.</li>
<li>The fast resume data will be more likely to be usable, regardless of crashes or
out of date data, since pieces won't move around.</li>
<li>Can be used with prioritizing files to 0.</li>
</ul>
</blockquote>
</div>
<div class="section" id="compact-allocation">
<h2>compact allocation</h2>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">Note that support for compact allocation is deprecated in libttorrent, and will
be removed in future versions.</p>
</div>
<p>The compact allocation will only allocate as much storage as it needs to keep the
pieces downloaded so far. This means that pieces will be moved around to be placed
at their final position in the files while downloading (to make sure the completed
download has all its pieces in the correct place). So, the main drawbacks are:</p>
<blockquote>
<ul class="simple">
<li>More disk operations while downloading since pieces are moved around.</li>
<li>Potentially more fragmentation in the filesystem.</li>
<li>Cannot be used while having files with priority 0.</li>
</ul>
</blockquote>
<p>The benefits though, are:</p>
<blockquote>
<ul class="simple">
<li>No startup delay, since the files don't need allocating.</li>
<li>The download will not use unnecessary disk space.</li>
<li>Disk caches perform much better than in full allocation and raises the download
speed limit imposed by the disk.</li>
<li>Works well on filesystems that don't support sparse files.</li>
</ul>
</blockquote>
<p>The algorithm that is used when allocating pieces and slots isn't very complicated.
For the interested, a description follows.</p>
<p>storing a piece:</p>
<ol class="arabic simple">
<li>let <strong>A</strong> be a newly downloaded piece, with index <strong>n</strong>.</li>
<li>let <strong>s</strong> be the number of slots allocated in the file we're
downloading to. (the number of pieces it has room for).</li>
<li>if <strong>n</strong> &gt;= <strong>s</strong> then allocate a new slot and put the piece there.</li>
<li>if <strong>n</strong> &lt; <strong>s</strong> then allocate a new slot, move the data at
slot <strong>n</strong> to the new slot and put <strong>A</strong> in slot <strong>n</strong>.</li>
</ol>
<p>allocating a new slot:</p>
<ol class="arabic simple">
<li>if there's an unassigned slot (a slot that doesn't
contain any piece), return that slot index.</li>
<li>append the new slot at the end of the file (or find an unused slot).</li>
<li>let <strong>i</strong> be the index of newly allocated slot</li>
<li>if we have downloaded piece index <strong>i</strong> already (to slot <strong>j</strong>) then<ol class="arabic">
<li>move the data at slot <strong>j</strong> to slot <strong>i</strong>.</li>
<li>return slot index <strong>j</strong> as the newly allocated free slot.</li>
</ol>
</li>
<li>return <strong>i</strong> as the newly allocated slot.</li>
</ol>
</div>
</div>
<div class="section" id="extensions">
<h1>extensions</h1>
<p>These extensions all operates within the <a class="reference external" href="extension_protocol.html">extension protocol</a>. The
name of the extension is the name used in the extension-list packets,
and the payload is the data in the extended message (not counting the
length-prefix, message-id nor extension-id).</p>
<p>Note that since this protocol relies on one of the reserved bits in the
handshake, it may be incompatible with future versions of the mainline
bittorrent client.</p>
<p>These are the extensions that are currently implemented.</p>
<div class="section" id="metadata-from-peers">
<h2>metadata from peers</h2>
<p>Extension name: &quot;LT_metadata&quot;</p>
<p>This extension is deprecated in favor of the more widely supported <tt class="docutils literal">ut_metadata</tt>
extension, see <a class="reference external" href="http://bittorrent.org/beps/bep_0009.html">BEP 9</a>.
The point with this extension is that you don't have to distribute the
metadata (.torrent-file) separately. The metadata can be distributed
through the bittorrent swarm. The only thing you need to download such
a torrent is the tracker url and the info-hash of the torrent.</p>
<p>It works by assuming that the initial seeder has the metadata and that
the metadata will propagate through the network as more peers join.</p>
<p>There are three kinds of messages in the metadata extension. These packets
are put as payload to the extension message. The three packets are:</p>
<blockquote>
<ul class="simple">
<li>request metadata</li>
<li>metadata</li>
<li>don't have metadata</li>
</ul>
</blockquote>
<p>request metadata:</p>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="23%" />
<col width="61%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">size</th>
<th class="head">name</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>uint8_t</td>
<td>msg_type</td>
<td>Determines the kind of message this is
0 means 'request metadata'</td>
</tr>
<tr><td>uint8_t</td>
<td>start</td>
<td>The start of the metadata block that
is requested. It is given in 256:ths
of the total size of the metadata,
since the requesting client don't know
the size of the metadata.</td>
</tr>
<tr><td>uint8_t</td>
<td>size</td>
<td>The size of the metadata block that is
requested. This is also given in
256:ths of the total size of the
metadata. The size is given as size-1.
That means that if this field is set
0, the request wants one 256:th of the
metadata.</td>
</tr>
</tbody>
</table>
<p>metadata:</p>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="23%" />
<col width="61%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">size</th>
<th class="head">name</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>uint8_t</td>
<td>msg_type</td>
<td>1 means 'metadata'</td>
</tr>
<tr><td>int32_t</td>
<td>total_size</td>
<td>The total size of the metadata, given
in number of bytes.</td>
</tr>
<tr><td>int32_t</td>
<td>offset</td>
<td>The offset of where the metadata block
in this message belongs in the final
metadata. This is given in bytes.</td>
</tr>
<tr><td>uint8_t[]</td>
<td>metadata</td>
<td>The actual metadata block. The size of
this part is given implicit by the
length prefix in the bittorrent
protocol packet.</td>
</tr>
</tbody>
</table>
<p>Don't have metadata:</p>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="23%" />
<col width="61%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">size</th>
<th class="head">name</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>uint8_t</td>
<td>msg_type</td>
<td>2 means 'I don't have metadata'.
This message is sent as a reply to a
metadata request if the the client
doesn't have any metadata.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="dont-have">
<h2>dont_have</h2>
<p>Extension name: &quot;lt_dont_have&quot;</p>
<p>The <tt class="docutils literal">dont_have</tt> extension message is used to tell peers that the client no longer
has a specific piece. The extension message should be advertised in the <tt class="docutils literal">m</tt> dictionary
as <tt class="docutils literal">lt_dont_have</tt>. The message format mimics the regular <tt class="docutils literal">HAVE</tt> bittorrent message.</p>
<p>Just like all extension messages, the first 2 bytes in the mssage itself are 20 (the
bittorrent extension message) and the message ID assigned to this extension in the <tt class="docutils literal">m</tt>
dictionary in the handshake.</p>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="23%" />
<col width="61%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">size</th>
<th class="head">name</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>uint32_t</td>
<td>piece</td>
<td>index of the piece the peer no longer
has.</td>
</tr>
</tbody>
</table>
<p>The length of this message (including the extension message prefix) is
6 bytes, i.e. one byte longer than the normal <tt class="docutils literal">HAVE</tt> message, because
of the extension message wrapping.</p>
</div>
<div class="section" id="http-seeding">
<h2>HTTP seeding</h2>
<p>There are two kinds of HTTP seeding. One with that assumes a smart
(and polite) client and one that assumes a smart server. These
are specified in <a class="reference external" href="http://bittorrent.org/beps/bep_0019.html">BEP 19</a> and <a class="reference external" href="http://bittorrent.org/beps/bep_0017.html">BEP 17</a> respectively.</p>
<p>libtorrent supports both. In the libtorrent source code and API,
BEP 19 urls are typically referred to as <em>url seeds</em> and BEP 17
urls are typically referred to as <em>HTTP seeds</em>.</p>
<p>The libtorrent implementation of <a class="reference external" href="http://bittorrent.org/beps/bep_0019.html">BEP 19</a> assumes that, if the URL ends with a slash
('/'), the filename should be appended to it in order to request pieces from
that file. The way this works is that if the torrent is a single-file torrent,
only that filename is appended. If the torrent is a multi-file torrent, the
torrent's name '/' the file name is appended. This is the same directory
structure that libtorrent will download torrents into.</p>
</div>
</div>
<div class="section" id="piece-picker">
<h1>piece picker</h1>
<p>The piece picker in libtorrent has the following features:</p>
<ul class="simple">
<li>rarest first</li>
<li>sequential download</li>
<li>random pick</li>
<li>reverse order picking</li>
<li>parole mode</li>
<li>prioritize partial pieces</li>
<li>prefer whole pieces</li>
<li>piece affinity by speed category</li>
<li>piece priorities</li>
</ul>
<div class="section" id="internal-representation">
<h2>internal representation</h2>
<p>It is optimized by, at all times, keeping a list of pieces ordered
by rarity, randomly shuffled within each rarity class. This list
is organized as a single vector of contigous memory in RAM, for
optimal memory locality and to eliminate heap allocations and frees
when updating rarity of pieces.</p>
<p>Expensive events, like a peer joining or leaving, are evaluated
lazily, since it's cheaper to rebuild the whole list rather than
updating every single piece in it. This means as long as no blocks
are picked, peers joining and leaving is no more costly than a single
peer joining or leaving. Of course the special cases of peers that have
all or no pieces are optimized to not require rebuilding the list.</p>
</div>
<div class="section" id="picker-strategy">
<h2>picker strategy</h2>
<p>The normal mode of the picker is of course <em>rarest first</em>, meaning
pieces that few peers have are preferred to be downloaded over pieces
that more peers have. This is a fundamental algorithm that is the
basis of the performance of bittorrent. However, the user may set the
piece picker into sequential download mode. This mode simply picks
pieces sequentially, always preferring lower piece indices.</p>
<p>When a torrent starts out, picking the rarest pieces means increased
risk that pieces won't be completed early (since there are only a few
peers they can be downloaded from), leading to a delay of having any
piece to offer to other peers. This lack of pieces to trade, delays
the client from getting started into the normal tit-for-tat mode of
bittorrent, and will result in a long ramp-up time. The heuristic to
mitigate this problem is to, for the first few pieces, pick random pieces
rather than rare pieces. The threshold for when to leave this initial
picker mode is determined by <a class="reference external" href="reference-Settings.html#initial_picker_threshold">session_settings::initial_picker_threshold</a>.</p>
</div>
<div class="section" id="reverse-order">
<h2>reverse order</h2>
<p>An orthogonal setting is <em>reverse order</em>, which is used for <em>snubbed</em>
peers. Snubbed peers are peers that appear very slow, and might have timed
out a piece request. The idea behind this is to make all snubbed peers
more likely to be able to do download blocks from the same piece,
concentrating slow peers on as few pieces as possible. The reverse order
means that the most common pieces are picked, instead of the rarest pieces
(or in the case of sequential download, the last pieces, intead of the first).</p>
</div>
<div class="section" id="parole-mode">
<h2>parole mode</h2>
<p>Peers that have participated in a piece that failed the hash check, may be
put in <em>parole mode</em>. This means we prefer downloading a full piece from this
peer, in order to distinguish which peer is sending corrupt data. Whether to
do this is or not is controlled by <a class="reference external" href="reference-Settings.html#use_parole_mode">session_settings::use_parole_mode</a>.</p>
<p>In parole mode, the piece picker prefers picking one whole piece at a time for
a given peer, avoiding picking any blocks from a piece any other peer has
contributed to (since that would defeat the purpose of parole mode).</p>
</div>
<div class="section" id="prioritize-partial-pieces">
<h2>prioritize partial pieces</h2>
<p>This setting determines if partially downloaded or requested pieces should always
be preferred over other pieces. The benefit of doing this is that the number of
partial pieces is minimized (and hence the turn-around time for downloading a block
until it can be uploaded to others is minimized). It also puts less stress on the
disk cache, since fewer partial pieces need to be kept in the cache. Whether or
not to enable this is controlled by <a class="reference external" href="reference-Settings.html#prioritize_partial_pieces">session_settings::prioritize_partial_pieces</a>.</p>
<p>The main benefit of not prioritizing partial pieces is that the rarest first
algorithm gets to have more influence on which pieces are picked. The picker is
more likely to truly pick the rarest piece, and hence improving the performance
of the swarm.</p>
<p>This setting is turned on automatically whenever the number of partial pieces
in the piece picker exceeds the number of peers we're connected to times 1.5.
This is in order to keep the waste of partial pieces to a minimum, but still
prefer rarest pieces.</p>
</div>
<div class="section" id="prefer-whole-pieces">
<h2>prefer whole pieces</h2>
<p>The <em>prefer whole pieces</em> setting makes the piece picker prefer picking entire
pieces at a time. This is used by web connections (both http seeding
standards), in order to be able to coalesce the small bittorrent requests
to larger HTTP requests. This significantly improves performance when
downloading over HTTP.</p>
<p>It is also used by peers that are downloading faster than a certain
threshold. The main advantage is that these peers will better utilize the
other peer's disk cache, by requesting all blocks in a single piece, from
the same peer.</p>
<p>This threshold is controlled by <a class="reference external" href="reference-Settings.html#whole_pieces_threshold">session_settings::whole_pieces_threshold</a>.</p>
<p><em>TODO: piece affinity by speed category</em>
<em>TODO: piece priorities</em></p>
</div>
</div>
<div class="section" id="ssl-torrents">
<h1>SSL torrents</h1>
<p>Torrents may have an SSL root (CA) certificate embedded in them. Such torrents
are called <em>SSL torrents</em>. An SSL torrent talks to all bittorrent peers over SSL.
The protocols are layered like this:</p>
<pre class="literal-block">
+-----------------------+
| BitTorrent protocol |
+-----------------------+
| SSL |
+-----------+-----------+
| TCP | uTP |
| +-----------+
| | UDP |
+-----------+-----------+
</pre>
<p>During the SSL handshake, both peers need to authenticate by providing a certificate
that is signed by the CA certificate found in the .torrent file. These peer
certificates are expected to be privided to peers through some other means than
bittorrent. Typically by a peer generating a certificate request which is sent to
the publisher of the torrent, and the publisher returning a signed certificate.</p>
<p>In libtorrent, <a class="reference external" href="reference-Core.html#set_ssl_certificate()">set_ssl_certificate()</a> in <a class="reference external" href="reference-Core.html#torrent_handle">torrent_handle</a> is used to tell libtorrent where
to find the peer certificate and the private key for it. When an SSL torrent is loaded,
the <a class="reference external" href="reference-Alerts.html#torrent_need_cert_alert">torrent_need_cert_alert</a> is posted to remind the user to provide a certificate.</p>
<p>A peer connecting to an SSL torrent MUST provide the <em>SNI</em> TLS extension (server name
indication). The server name is the hex encoded info-hash of the torrent to connect to.
This is required for the client accepting the connection to know which certificate to
present.</p>
<p>SSL connections are accepted on a separate socket from normal bittorrent connections. To
pick which port the SSL socket should bind to, set <a class="reference external" href="reference-Settings.html#ssl_listen">session_settings::ssl_listen</a> to a
different port. It defaults to port 4433. This setting is only taken into account when the
normal listen socket is opened (i.e. just changing this setting won't necessarily close
and re-open the SSL socket). To not listen on an SSL socket at all, set <tt class="docutils literal">ssl_listen</tt> to 0.</p>
<p>This feature is only available if libtorrent is build with openssl support (<tt class="docutils literal">TORRENT_USE_OPENSSL</tt>)
and requires at least openSSL version 1.0, since it needs SNI support.</p>
<p>Peer certificates must have at least one <em>SubjectAltName</em> field of type dNSName. At least
one of the fields must <em>exactly</em> match the name of the torrent. This is a byte-by-byte comparison,
the UTF-8 encoding must be identical (i.e. there's no unicode normalization going on). This is
the recommended way of verifying certificates for HTTPS servers according to <a class="reference external" href="http://www.ietf.org/rfc/rfc2818.txt">RFC 2818</a>. Note
the difference that for torrents only <em>dNSName</em> fields are taken into account (not IP address fields).
The most specific (i.e. last) <em>Common Name</em> field is also taken into account if no <em>SubjectAltName</em>
did not match.</p>
<p>If any of these fields contain a single asterisk (&quot;*&quot;), the certificate is considered covering
any torrent, allowing it to be reused for any torrent.</p>
<p>The purpose of matching the torrent name with the fields in the peer certificate is to allow
a publisher to have a single root certificate for all torrents it distributes, and issue
separate peer certificates for each torrent. A peer receiving a certificate will not necessarily
be able to access all torrents published by this root certificate (only if it has a &quot;star cert&quot;).</p>
<div class="section" id="testing">
<h2>testing</h2>
<p>To test incoming SSL connections to an SSL torrent, one can use the following <em>openssl</em> command:</p>
<pre class="literal-block">
openssl s_client -cert &lt;peer-certificate&gt;.pem -key &lt;peer-private-key&gt;.pem -CAfile \
&lt;torrent-cert&gt;.pem -debug -connect 127.0.0.1:4433 -tls1 -servername &lt;info-hash&gt;
</pre>
<p>To create a root certificate, the Distinguished Name (<em>DN</em>) is not taken into account
by bittorrent peers. You still need to specify something, but from libtorrent's point of
view, it doesn't matter what it is. libtorrent only makes sure the peer certificates are
signed by the correct root certificate.</p>
<p>One way to create the certificates is to use the <tt class="docutils literal">CA.sh</tt> script that comes with openssl,
like thisi (don't forget to enter a common Name for the certificate):</p>
<pre class="literal-block">
CA.sh -newca
CA.sh -newreq
CA.sh -sign
</pre>
<p>The torrent certificate is located in <tt class="docutils literal">./demoCA/private/demoCA/cacert.pem</tt>, this is
the pem file to include in the .torrent file.</p>
<p>The peer's certificate is located in <tt class="docutils literal">./newcert.pem</tt> and the certificate's
private key in <tt class="docutils literal">./newkey.pem</tt>.</p>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

2254
docs/reference-Alerts.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,835 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Bencoding</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="bencoding">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Bencoding</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#invalid-encoding" id="id55">invalid_encoding</a></li>
<li><a class="reference internal" href="#type-error" id="id56">type_error</a></li>
<li><a class="reference internal" href="#entry" id="id57">entry</a></li>
<li><a class="reference internal" href="#pascal-string" id="id58">pascal_string</a></li>
<li><a class="reference internal" href="#lazy-entry" id="id59">lazy_entry</a></li>
</ul>
</div>
<p>Bencoding is a common representation in bittorrent used for
for dictionary, list, int and string hierarchies. It's used
to encode .torrent files and some messages in the network
protocol. libtorrent also uses it to store settings, resume
data and other state between sessions.</p>
<p>Strings in bencoded structures are not necessarily representing
text. Strings are raw byte buffers of a certain length. If a
string is meant to be interpreted as text, it is required to
be UTF-8 encoded. See <a class="reference external" href="http://bittorrent.org/beps/bep_0003.html">BEP 3</a>.</p>
<p>There are two mechanims to <em>decode</em> bencoded buffers in libtorrent.</p>
<p>The most flexible one is <a class="reference external" href="reference-Bencoding.html#bdecode()">bdecode()</a>, which returns a structure
represented by <a class="reference external" href="reference-Bencoding.html#entry">entry</a>. When a buffer is decoded with this function,
it can be discarded. The <a class="reference external" href="reference-Bencoding.html#entry">entry</a> does not contain any references back
to it. This means that <a class="reference external" href="reference-Bencoding.html#bdecode()">bdecode()</a> actually copies all the data out
of the buffer and into its own hierarchy. This makes this
function potentially expensive, if you're parsing large amounts
of data.</p>
<p>Another consideration is that <a class="reference external" href="reference-Bencoding.html#bdecode()">bdecode()</a> is a recursive parser.
For this reason, in order to avoid DoS attacks by triggering
a stack overflow, there is a recursion limit. This limit is
a sanity check to make sure it doesn't run the risk of
busting the stack.</p>
<p>The second mechanism is <a class="reference external" href="reference-Bencoding.html#lazy_bdecode()">lazy_bdecode()</a>, which returns a
bencoded structure represented by <a class="reference external" href="reference-Bencoding.html#lazy_entry">lazy_entry</a>. This function
builds a tree that points back into the original buffer.
The returned <a class="reference external" href="reference-Bencoding.html#lazy_entry">lazy_entry</a> will not be valid once the buffer
it was parsed out of is discarded.</p>
<p>Not only is this function more efficient because of less
memory allocation and data copy, the parser is also not
recursive, which means it probably performs a little bit
better and can have a higher recursion limit on the structures
it's parsing.</p>
<a name="invalid_encoding"></a><div class="section" id="invalid-encoding">
<h1>invalid_encoding</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/bencode.hpp">libtorrent/bencode.hpp</a>&quot;</p>
<p>thrown by <a class="reference external" href="reference-Bencoding.html#bdecode()">bdecode()</a> if the provided bencoded buffer does not contain
valid encoding.</p>
<pre class="literal-block">
struct invalid_encoding: std::exception
{
virtual const char* <strong>what</strong> () const throw();
};
</pre>
<a name="type_error"></a></div>
<div class="section" id="type-error">
<h1>type_error</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/entry.hpp">libtorrent/entry.hpp</a>&quot;</p>
<p>thrown by any accessor function of <a class="reference external" href="reference-Bencoding.html#entry">entry</a> if the accessor
function requires a type different than the actual type
of the <a class="reference external" href="reference-Bencoding.html#entry">entry</a> object.</p>
<pre class="literal-block">
struct type_error: std::runtime_error
{
<strong>type_error</strong> (const char* error);
};
</pre>
<a name="entry"></a></div>
<div class="section" id="entry">
<h1>entry</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/entry.hpp">libtorrent/entry.hpp</a>&quot;</p>
<p>The <tt class="docutils literal">entry</tt> class represents one node in a bencoded hierarchy. It works as a
variant type, it can be either a list, a dictionary (<tt class="docutils literal"><span class="pre">std::map</span></tt>), an integer
or a string.</p>
<pre class="literal-block">
class entry
{
data_type <strong>type</strong> () const;
<strong>entry</strong> (list_type const&amp;);
<strong>entry</strong> (integer_type const&amp;);
<strong>entry</strong> (dictionary_type const&amp;);
<strong>entry</strong> (string_type const&amp;);
<strong>entry</strong> (data_type t);
void <strong>operator=</strong> (string_type const&amp;);
void <strong>operator=</strong> (entry const&amp;);
void <strong>operator=</strong> (integer_type const&amp;);
void <strong>operator=</strong> (lazy_entry const&amp;);
void <strong>operator=</strong> (dictionary_type const&amp;);
void <strong>operator=</strong> (list_type const&amp;);
const integer_type&amp; <strong>integer</strong> () const;
const string_type&amp; <strong>string</strong> () const;
const dictionary_type&amp; <strong>dict</strong> () const;
string_type&amp; <strong>string</strong> ();
list_type&amp; <strong>list</strong> ();
dictionary_type&amp; <strong>dict</strong> ();
integer_type&amp; <strong>integer</strong> ();
const list_type&amp; <strong>list</strong> () const;
void <strong>swap</strong> (entry&amp; e);
entry&amp; <strong>operator[]</strong> (std::string const&amp; key);
const entry&amp; <strong>operator[]</strong> (std::string const&amp; key) const;
entry&amp; <strong>operator[]</strong> (char const* key);
const entry&amp; <strong>operator[]</strong> (char const* key) const;
entry const* <strong>find_key</strong> (char const* key) const;
entry* <strong>find_key</strong> (char const* key);
entry* <strong>find_key</strong> (std::string const&amp; key);
entry const* <strong>find_key</strong> (std::string const&amp; key) const;
std::string <strong>to_string</strong> () const;
enum data_type
{
int_t,
string_t,
list_t,
dictionary_t,
undefined_t,
};
mutable boost::uint8_t m_type_queried:1;
};
</pre>
<a name="type()"></a><div class="section" id="type">
<h2>type()</h2>
<pre class="literal-block">
data_type <strong>type</strong> () const;
</pre>
<p>returns the concrete type of the <a class="reference external" href="reference-Bencoding.html#entry">entry</a></p>
<a name="entry()"></a></div>
<div class="section" id="id16">
<h2>entry()</h2>
<pre class="literal-block">
<strong>entry</strong> (list_type const&amp;);
<strong>entry</strong> (integer_type const&amp;);
<strong>entry</strong> (dictionary_type const&amp;);
<strong>entry</strong> (string_type const&amp;);
</pre>
<p>constructors directly from a specific type.
The content of the argument is copied into the
newly constructed <a class="reference external" href="reference-Bencoding.html#entry">entry</a></p>
<a name="entry()"></a></div>
<div class="section" id="id18">
<h2>entry()</h2>
<pre class="literal-block">
<strong>entry</strong> (data_type t);
</pre>
<p>construct an empty <a class="reference external" href="reference-Bencoding.html#entry">entry</a> of the specified type.
see <a class="reference external" href="reference-Bencoding.html#data_type">data_type</a> enum.</p>
<a name="operator=()"></a></div>
<div class="section" id="operator">
<h2>operator=()</h2>
<pre class="literal-block">
void <strong>operator=</strong> (string_type const&amp;);
void <strong>operator=</strong> (entry const&amp;);
void <strong>operator=</strong> (integer_type const&amp;);
void <strong>operator=</strong> (lazy_entry const&amp;);
void <strong>operator=</strong> (dictionary_type const&amp;);
void <strong>operator=</strong> (list_type const&amp;);
</pre>
<p>copies the structure of the right hand side into this
entry.</p>
<a name="string()"></a>
<a name="dict()"></a>
<a name="integer()"></a>
<a name="list()"></a></div>
<div class="section" id="string-dict-integer-list">
<h2>string() dict() integer() list()</h2>
<pre class="literal-block">
const integer_type&amp; <strong>integer</strong> () const;
const string_type&amp; <strong>string</strong> () const;
const dictionary_type&amp; <strong>dict</strong> () const;
string_type&amp; <strong>string</strong> ();
list_type&amp; <strong>list</strong> ();
dictionary_type&amp; <strong>dict</strong> ();
integer_type&amp; <strong>integer</strong> ();
const list_type&amp; <strong>list</strong> () const;
</pre>
<p>The <tt class="docutils literal">integer()</tt>, <tt class="docutils literal">string()</tt>, <tt class="docutils literal">list()</tt> and <tt class="docutils literal">dict()</tt> functions
are accessors that return the respective type. If the <tt class="docutils literal">entry</tt> object isn't of the
type you request, the accessor will throw <a class="reference external" href="reference-Error_Codes.html#libtorrent_exception">libtorrent_exception</a> (which derives from
<tt class="docutils literal"><span class="pre">std::runtime_error</span></tt>). You can ask an <tt class="docutils literal">entry</tt> for its type through the
<tt class="docutils literal">type()</tt> function.</p>
<p>If you want to create an <tt class="docutils literal">entry</tt> you give it the type you want it to have in its
constructor, and then use one of the non-const accessors to get a reference which you then
can assign the value you want it to have.</p>
<p>The typical code to get info from a torrent file will then look like this:</p>
<pre class="literal-block">
entry torrent_file;
// ...
// throws if this is not a dictionary
entry::dictionary_type const&amp; dict = torrent_file.dict();
entry::dictionary_type::const_iterator i;
i = dict.find(&quot;announce&quot;);
if (i != dict.end())
{
std::string tracker_url = i-&gt;second.string();
std::cout &lt;&lt; tracker_url &lt;&lt; &quot;\n&quot;;
}
</pre>
<p>The following code is equivalent, but a little bit shorter:</p>
<pre class="literal-block">
entry torrent_file;
// ...
// throws if this is not a dictionary
if (entry* i = torrent_file.find_key(&quot;announce&quot;))
{
std::string tracker_url = i-&gt;string();
std::cout &lt;&lt; tracker_url &lt;&lt; &quot;\n&quot;;
}
</pre>
<p>To make it easier to extract information from a torrent file, the class <a class="reference external" href="reference-Core.html#torrent_info">torrent_info</a>
exists.</p>
<a name="swap()"></a></div>
<div class="section" id="swap">
<h2>swap()</h2>
<pre class="literal-block">
void <strong>swap</strong> (entry&amp; e);
</pre>
<p>swaps the content of <em>this</em> with <tt class="docutils literal">e</tt>.</p>
<a name="operator[]()"></a></div>
<div class="section" id="id23">
<h2>operator[]()</h2>
<pre class="literal-block">
entry&amp; <strong>operator[]</strong> (std::string const&amp; key);
const entry&amp; <strong>operator[]</strong> (std::string const&amp; key) const;
entry&amp; <strong>operator[]</strong> (char const* key);
const entry&amp; <strong>operator[]</strong> (char const* key) const;
</pre>
<p>All of these functions requires the <a class="reference external" href="reference-Bencoding.html#entry">entry</a> to be a dictionary, if it isn't they
will throw <tt class="docutils literal"><span class="pre">libtorrent::type_error</span></tt>.</p>
<p>The non-const versions of the <tt class="docutils literal">operator[]</tt> will return a reference to either
the existing element at the given key or, if there is no element with the
given key, a reference to a newly inserted element at that key.</p>
<p>The const version of <tt class="docutils literal">operator[]</tt> will only return a reference to an
existing element at the given key. If the key is not found, it will throw
<tt class="docutils literal"><span class="pre">libtorrent::type_error</span></tt>.</p>
<a name="find_key()"></a></div>
<div class="section" id="find-key">
<h2>find_key()</h2>
<pre class="literal-block">
entry const* <strong>find_key</strong> (char const* key) const;
entry* <strong>find_key</strong> (char const* key);
entry* <strong>find_key</strong> (std::string const&amp; key);
entry const* <strong>find_key</strong> (std::string const&amp; key) const;
</pre>
<p>These functions requires the <a class="reference external" href="reference-Bencoding.html#entry">entry</a> to be a dictionary, if it isn't they
will throw <tt class="docutils literal"><span class="pre">libtorrent::type_error</span></tt>.</p>
<p>They will look for an element at the given key in the dictionary, if the
element cannot be found, they will return 0. If an element with the given
key is found, the return a pointer to it.</p>
<a name="data_type"></a></div>
<div class="section" id="enum-data-type">
<h2>enum data_type</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/entry.hpp">libtorrent/entry.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="41%" />
<col width="21%" />
<col width="38%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>int_t</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr><td>string_t</td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr><td>list_t</td>
<td>2</td>
<td>&nbsp;</td>
</tr>
<tr><td>dictionary_t</td>
<td>3</td>
<td>&nbsp;</td>
</tr>
<tr><td>undefined_t</td>
<td>4</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<a name="m_type_queried"></a><dl class="docutils">
<dt>m_type_queried</dt>
<dd>in debug mode this is set to false by bdecode
to indicate that the program has not yet queried
the type of this <a class="reference external" href="reference-Bencoding.html#entry">entry</a>, and sould not assume
that it has a certain type. This is asserted in
the accessor functions. This does not apply if
exceptions are used.</dd>
</dl>
<a name="pascal_string"></a></div>
</div>
<div class="section" id="pascal-string">
<h1>pascal_string</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/lazy_entry.hpp">libtorrent/lazy_entry.hpp</a>&quot;</p>
<p>this is a string that is not NULL-terminated. Instead it
comes with a length, specified in bytes. This is particularly
useful when parsing bencoded structures, because strings are
not NULL-terminated internally, and requiring NULL termination
would require copying the string.</p>
<p>see <a class="reference external" href="reference-Bencoding.html#string_pstr()">lazy_entry::string_pstr()</a>.</p>
<pre class="literal-block">
struct pascal_string
{
<strong>pascal_string</strong> (char const* p, int l);
bool <strong>operator&lt;</strong> (pascal_string const&amp; rhs) const;
int len;
char const* ptr;
};
</pre>
<a name="pascal_string()"></a><div class="section" id="id30">
<h2>pascal_string()</h2>
<pre class="literal-block">
<strong>pascal_string</strong> (char const* p, int l);
</pre>
<p>construct a string pointing to the characters at <tt class="docutils literal">p</tt>
of length <tt class="docutils literal">l</tt> characters. No NULL termination is required.</p>
<a name="operator<()"></a></div>
<div class="section" id="id31">
<h2>operator&lt;()</h2>
<pre class="literal-block">
bool <strong>operator&lt;</strong> (pascal_string const&amp; rhs) const;
</pre>
<p>lexicographical comparison of strings. Order is consisten
with memcmp.</p>
<a name="len"></a><dl class="docutils">
<dt>len</dt>
<dd>the number of characters in the string.</dd>
</dl>
<a name="ptr"></a><dl class="docutils">
<dt>ptr</dt>
<dd>the pointer to the first character in the string. This is
not NULL terminated, but instead consult the <tt class="docutils literal">len</tt> field
to know how many characters follow.</dd>
</dl>
<a name="lazy_entry"></a></div>
</div>
<div class="section" id="lazy-entry">
<h1>lazy_entry</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/lazy_entry.hpp">libtorrent/lazy_entry.hpp</a>&quot;</p>
<p>this object represent a node in a bencoded structure. It is a variant
type whose concrete type is one of:</p>
<ol class="arabic simple">
<li>dictionary (maps strings -&gt; <a class="reference external" href="reference-Bencoding.html#lazy_entry">lazy_entry</a>)</li>
<li>list (sequence of <a class="reference external" href="reference-Bencoding.html#lazy_entry">lazy_entry</a>, i.e. heterogenous)</li>
<li>integer</li>
<li>string</li>
</ol>
<p>There is also a <tt class="docutils literal">none</tt> type, which is used for uninitialized
lazy_entries.</p>
<pre class="literal-block">
struct lazy_entry
{
entry_type_t <strong>type</strong> () const;
void <strong>construct_int</strong> (char const* start, int length);
boost::int64_t <strong>int_value</strong> () const;
char const* <strong>string_ptr</strong> () const;
char const* <strong>string_cstr</strong> () const;
pascal_string <strong>string_pstr</strong> () const;
std::string <strong>string_value</strong> () const;
int <strong>string_length</strong> () const;
lazy_entry const* <strong>dict_find_string</strong> (char const* name) const;
lazy_entry* <strong>dict_find</strong> (char const* name);
lazy_entry const* <strong>dict_find</strong> (char const* name) const;
pascal_string <strong>dict_find_pstr</strong> (char const* name) const;
std::string <strong>dict_find_string_value</strong> (char const* name) const;
boost::int64_t <strong>dict_find_int_value</strong> (char const* name, boost::int64_t default_val = 0) const;
lazy_entry const* <strong>dict_find_int</strong> (char const* name) const;
lazy_entry const* <strong>dict_find_list</strong> (char const* name) const;
lazy_entry const* <strong>dict_find_dict</strong> (char const* name) const;
std::pair&lt;std::string, lazy_entry const*&gt; <strong>dict_at</strong> (int i) const;
int <strong>dict_size</strong> () const;
lazy_entry* <strong>list_at</strong> (int i);
lazy_entry const* <strong>list_at</strong> (int i) const;
std::string <strong>list_string_value_at</strong> (int i) const;
pascal_string <strong>list_pstr_at</strong> (int i) const;
boost::int64_t <strong>list_int_value_at</strong> (int i, boost::int64_t default_val = 0) const;
int <strong>list_size</strong> () const;
std::pair&lt;char const*, int&gt; <strong>data_section</strong> () const;
void <strong>swap</strong> (lazy_entry&amp; e);
enum entry_type_t
{
none_t,
dict_t,
list_t,
string_t,
int_t,
};
};
</pre>
<a name="type()"></a><div class="section" id="id35">
<h2>type()</h2>
<pre class="literal-block">
entry_type_t <strong>type</strong> () const;
</pre>
<p>tells you which specific type this lazy <a class="reference external" href="reference-Bencoding.html#entry">entry</a> has.
See <a class="reference external" href="reference-Bencoding.html#entry_type_t">entry_type_t</a>. The type determines which subset of
member functions are valid to use.</p>
<a name="construct_int()"></a></div>
<div class="section" id="construct-int">
<h2>construct_int()</h2>
<pre class="literal-block">
void <strong>construct_int</strong> (char const* start, int length);
</pre>
<p>start points to the first decimal digit
length is the number of digits</p>
<a name="int_value()"></a></div>
<div class="section" id="int-value">
<h2>int_value()</h2>
<pre class="literal-block">
boost::int64_t <strong>int_value</strong> () const;
</pre>
<p>requires the type to be an integer. return the integer value</p>
<a name="string_ptr()"></a></div>
<div class="section" id="string-ptr">
<h2>string_ptr()</h2>
<pre class="literal-block">
char const* <strong>string_ptr</strong> () const;
</pre>
<p>the string is not null-terminated!
use <a class="reference external" href="reference-Bencoding.html#string_length()">string_length()</a> to determine how many bytes
are part of the string.</p>
<a name="string_cstr()"></a></div>
<div class="section" id="string-cstr">
<h2>string_cstr()</h2>
<pre class="literal-block">
char const* <strong>string_cstr</strong> () const;
</pre>
<p>this will return a null terminated string
it will write to the source buffer!</p>
<a name="string_pstr()"></a></div>
<div class="section" id="string-pstr">
<h2>string_pstr()</h2>
<pre class="literal-block">
pascal_string <strong>string_pstr</strong> () const;
</pre>
<p>if this is a string, returns a <a class="reference external" href="reference-Bencoding.html#pascal_string">pascal_string</a>
representing the string value.</p>
<a name="string_value()"></a></div>
<div class="section" id="string-value">
<h2>string_value()</h2>
<pre class="literal-block">
std::string <strong>string_value</strong> () const;
</pre>
<p>if this is a string, returns the string as a std::string.
(which requires a copy)</p>
<a name="string_length()"></a></div>
<div class="section" id="string-length">
<h2>string_length()</h2>
<pre class="literal-block">
int <strong>string_length</strong> () const;
</pre>
<p>if the <a class="reference external" href="reference-Bencoding.html#lazy_entry">lazy_entry</a> is a string, returns the
length of the string, in bytes.</p>
<a name="dict_find()"></a>
<a name="dict_find_string()"></a></div>
<div class="section" id="dict-find-dict-find-string">
<h2>dict_find() dict_find_string()</h2>
<pre class="literal-block">
lazy_entry const* <strong>dict_find_string</strong> (char const* name) const;
lazy_entry* <strong>dict_find</strong> (char const* name);
lazy_entry const* <strong>dict_find</strong> (char const* name) const;
</pre>
<p>if this is a dictionary, look for a key <tt class="docutils literal">name</tt>, and return
a pointer to its value, or NULL if there is none.</p>
<a name="dict_find_pstr()"></a>
<a name="dict_find_string_value()"></a></div>
<div class="section" id="dict-find-pstr-dict-find-string-value">
<h2>dict_find_pstr() dict_find_string_value()</h2>
<pre class="literal-block">
pascal_string <strong>dict_find_pstr</strong> (char const* name) const;
std::string <strong>dict_find_string_value</strong> (char const* name) const;
</pre>
<p>if this is a dictionary, look for a key <tt class="docutils literal">name</tt> whose value
is a string. If such key exist, return a pointer to
its value, otherwise NULL.</p>
<a name="dict_find_int_value()"></a>
<a name="dict_find_int()"></a></div>
<div class="section" id="dict-find-int-value-dict-find-int">
<h2>dict_find_int_value() dict_find_int()</h2>
<pre class="literal-block">
boost::int64_t <strong>dict_find_int_value</strong> (char const* name, boost::int64_t default_val = 0) const;
lazy_entry const* <strong>dict_find_int</strong> (char const* name) const;
</pre>
<p>if this is a dictionary, look for a key <tt class="docutils literal">name</tt> whose value
is an int. If such key exist, return a pointer to its value,
otherwise NULL.</p>
<a name="dict_find_list()"></a>
<a name="dict_find_dict()"></a></div>
<div class="section" id="dict-find-list-dict-find-dict">
<h2>dict_find_list() dict_find_dict()</h2>
<pre class="literal-block">
lazy_entry const* <strong>dict_find_list</strong> (char const* name) const;
lazy_entry const* <strong>dict_find_dict</strong> (char const* name) const;
</pre>
<p>these functions require that <tt class="docutils literal">this</tt> is a dictionary.
(this-&gt;type() == dict_t). They look for an element with the
specified name in the dictionary. <tt class="docutils literal">dict_find_dict</tt> only
finds dictionaries and <tt class="docutils literal">dict_find_list</tt> only finds lists.
if no key with the corresponding value of the right type is
found, NULL is returned.</p>
<a name="dict_at()"></a></div>
<div class="section" id="dict-at">
<h2>dict_at()</h2>
<pre class="literal-block">
std::pair&lt;std::string, lazy_entry const*&gt; <strong>dict_at</strong> (int i) const;
</pre>
<p>if this is a dictionary, return the key value pair at
position <tt class="docutils literal">i</tt> from the dictionary.</p>
<a name="dict_size()"></a></div>
<div class="section" id="dict-size">
<h2>dict_size()</h2>
<pre class="literal-block">
int <strong>dict_size</strong> () const;
</pre>
<p>requires that <tt class="docutils literal">this</tt> is a dictionary. return the
number of items in it</p>
<a name="list_at()"></a></div>
<div class="section" id="list-at">
<h2>list_at()</h2>
<pre class="literal-block">
lazy_entry* <strong>list_at</strong> (int i);
lazy_entry const* <strong>list_at</strong> (int i) const;
</pre>
<p>requires that <tt class="docutils literal">this</tt> is a list. return
the item at index <tt class="docutils literal">i</tt>.</p>
<a name="list_string_value_at()"></a>
<a name="list_pstr_at()"></a></div>
<div class="section" id="list-string-value-at-list-pstr-at">
<h2>list_string_value_at() list_pstr_at()</h2>
<pre class="literal-block">
std::string <strong>list_string_value_at</strong> (int i) const;
pascal_string <strong>list_pstr_at</strong> (int i) const;
</pre>
<p>these functions require <tt class="docutils literal">this</tt> to have the type list.
(this-&gt;type() == list_t). <tt class="docutils literal">list_string_value_at</tt> returns
the string at index <tt class="docutils literal">i</tt>. <tt class="docutils literal">list_pstr_at</tt>
returns a <a class="reference external" href="reference-Bencoding.html#pascal_string">pascal_string</a> of the string value at index <tt class="docutils literal">i</tt>.
if the element at <tt class="docutils literal">i</tt> is not a string, an empty string
is returned.</p>
<a name="list_int_value_at()"></a></div>
<div class="section" id="list-int-value-at">
<h2>list_int_value_at()</h2>
<pre class="literal-block">
boost::int64_t <strong>list_int_value_at</strong> (int i, boost::int64_t default_val = 0) const;
</pre>
<p>this function require <tt class="docutils literal">this</tt> to have the type list.
(this-&gt;type() == list_t). returns the integer value at
index <tt class="docutils literal">i</tt>. If the element at <tt class="docutils literal">i</tt> is not an integer
<tt class="docutils literal">default_val</tt> is returned, which defaults to 0.</p>
<a name="list_size()"></a></div>
<div class="section" id="list-size">
<h2>list_size()</h2>
<pre class="literal-block">
int <strong>list_size</strong> () const;
</pre>
<p>if this is a list, return the number of items in it.</p>
<a name="data_section()"></a></div>
<div class="section" id="data-section">
<h2>data_section()</h2>
<pre class="literal-block">
std::pair&lt;char const*, int&gt; <strong>data_section</strong> () const;
</pre>
<p>returns pointers into the source buffer where
this <a class="reference external" href="reference-Bencoding.html#entry">entry</a> has its bencoded data</p>
<a name="swap()"></a></div>
<div class="section" id="id43">
<h2>swap()</h2>
<pre class="literal-block">
void <strong>swap</strong> (lazy_entry&amp; e);
</pre>
<p>swap values of <tt class="docutils literal">this</tt> and <tt class="docutils literal">e</tt>.</p>
<a name="entry_type_t"></a></div>
<div class="section" id="enum-entry-type-t">
<h2>enum entry_type_t</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/lazy_entry.hpp">libtorrent/lazy_entry.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="33%" />
<col width="23%" />
<col width="43%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>none_t</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr><td>dict_t</td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr><td>list_t</td>
<td>2</td>
<td>&nbsp;</td>
</tr>
<tr><td>string_t</td>
<td>3</td>
<td>&nbsp;</td>
</tr>
<tr><td>int_t</td>
<td>4</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<a name="bdecode()"></a>
<a name="bencode()"></a></div>
<div class="section" id="bdecode-bencode">
<h2>bdecode() bencode()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/bencode.hpp">libtorrent/bencode.hpp</a>&quot;</p>
<pre class="literal-block">
template&lt;class InIt&gt; entry <strong>bdecode</strong> (InIt start, InIt end);
template&lt;class OutIt&gt; int <strong>bencode</strong> (OutIt out, const entry&amp; e);
template&lt;class InIt&gt; entry <strong>bdecode</strong> (InIt start, InIt end, int&amp; len);
</pre>
<p>These functions will encode data to <a class="reference external" href="http://wiki.theory.org/index.php/BitTorrentSpecification">bencoded</a> or decode <a class="reference external" href="http://wiki.theory.org/index.php/BitTorrentSpecification">bencoded</a> data.</p>
<p>If possible, <a class="reference external" href="reference-Bencoding.html#lazy_bdecode()">lazy_bdecode()</a> should be preferred over <tt class="docutils literal">bdecode()</tt>.</p>
<p>The <a class="reference internal" href="#entry">entry</a> class is the internal representation of the bencoded data
and it can be used to retrieve information, an <a class="reference internal" href="#entry">entry</a> can also be build by
the program and given to <tt class="docutils literal">bencode()</tt> to encode it into the <tt class="docutils literal">OutIt</tt>
iterator.</p>
<p>The <tt class="docutils literal">OutIt</tt> and <tt class="docutils literal">InIt</tt> are iterators
(<a class="reference external" href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> and <a class="reference external" href="http://www.sgi.com/tech/stl/OutputIterator.html">OutputIterator</a> respectively). They
are templates and are usually instantiated as <a class="reference external" href="http://www.sgi.com/tech/stl/ostream_iterator.html">ostream_iterator</a>,
<a class="reference external" href="http://www.sgi.com/tech/stl/back_insert_iterator.html">back_insert_iterator</a> or <a class="reference external" href="http://www.sgi.com/tech/stl/istream_iterator.html">istream_iterator</a>. These
functions will assume that the iterator refers to a character
(<tt class="docutils literal">char</tt>). So, if you want to encode <a class="reference external" href="reference-Bencoding.html#entry">entry</a> <tt class="docutils literal">e</tt> into a buffer
in memory, you can do it like this:</p>
<pre class="literal-block">
std::vector&lt;char&gt; buffer;
bencode(std::back_inserter(buf), e);
</pre>
<p>If you want to decode a torrent file from a buffer in memory, you can do it like this:</p>
<pre class="literal-block">
std::vector&lt;char&gt; buffer;
// ...
entry e = bdecode(buf.begin(), buf.end());
</pre>
<p>Or, if you have a raw char buffer:</p>
<pre class="literal-block">
const char* buf;
// ...
entry e = bdecode(buf, buf + data_size);
</pre>
<p>Now we just need to know how to retrieve information from the <a class="reference external" href="reference-Bencoding.html#entry">entry</a>.</p>
<p>If <tt class="docutils literal">bdecode()</tt> encounters invalid encoded data in the range given to it
it will throw <a class="reference external" href="reference-Error_Codes.html#libtorrent_exception">libtorrent_exception</a>.</p>
<a name="operator<<()"></a></div>
<div class="section" id="id50">
<h2>operator&lt;&lt;()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/entry.hpp">libtorrent/entry.hpp</a>&quot;</p>
<pre class="literal-block">
inline std::ostream&amp; <strong>operator&lt;&lt;</strong> (std::ostream&amp; os, const entry&amp; e);
</pre>
<a name="lazy_bdecode()"></a></div>
<div class="section" id="lazy-bdecode">
<h2>lazy_bdecode()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/lazy_entry.hpp">libtorrent/lazy_entry.hpp</a>&quot;</p>
<pre class="literal-block">
int <strong>lazy_bdecode</strong> (char const* start, char const* end
, lazy_entry&amp; ret, error_code&amp; ec, int* error_pos = 0
, int depth_limit = 1000, int item_limit = 1000000);
</pre>
<p>This function decodes <a class="reference external" href="http://wiki.theory.org/index.php/BitTorrentSpecification">bencoded</a> data.</p>
<p>Whenever possible, <tt class="docutils literal">lazy_bdecode()</tt> should be preferred over <tt class="docutils literal">bdecode()</tt>.
It is more efficient and more secure. It supports having constraints on the
amount of memory is consumed by the parser.</p>
<p><em>lazy</em> refers to the fact that it doesn't copy any actual data out of the
bencoded buffer. It builds a tree of <tt class="docutils literal">lazy_entry</tt> which has pointers into
the bencoded buffer. This makes it very fast and efficient. On top of that,
it is not recursive, which saves a lot of stack space when parsing deeply
nested trees. However, in order to protect against potential attacks, the
<tt class="docutils literal">depth_limit</tt> and <tt class="docutils literal">item_limit</tt> control how many levels deep the tree is
allowed to get. With recursive parser, a few thousand levels would be enough
to exhaust the threads stack and terminate the process. The <tt class="docutils literal">item_limit</tt>
protects against very large structures, not necessarily deep. Each bencoded
item in the structure causes the parser to allocate some amount of memory,
this memory is constant regardless of how much data actually is stored in
the item. One potential attack is to create a bencoded list of hundreds of
thousands empty strings, which would cause the parser to allocate a significant
amount of memory, perhaps more than is available on the machine, and effectively
provide a denial of service. The default item limit is set as a reasonable
upper limit for desktop computers. Very few torrents have more items in them.
The limit corresponds to about 25 MB, which might be a bit much for embedded
systems.</p>
<p><tt class="docutils literal">start</tt> and <tt class="docutils literal">end</tt> defines the bencoded buffer to be decoded. <tt class="docutils literal">ret</tt> is
the <tt class="docutils literal">lazy_entry</tt> which is filled in with the whole decoded tree. <tt class="docutils literal">ec</tt>
is a reference to an <tt class="docutils literal">error_code</tt> which is set to describe the error encountered
in case the function fails. <tt class="docutils literal">error_pos</tt> is an optional pointer to an int,
which will be set to the byte offset into the buffer where an error occurred,
in case the function fails.</p>
<a name="get_bdecode_category()"></a></div>
<div class="section" id="get-bdecode-category">
<h2>get_bdecode_category()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/lazy_entry.hpp">libtorrent/lazy_entry.hpp</a>&quot;</p>
<pre class="literal-block">
boost::system::error_category&amp; <strong>get_bdecode_category</strong> ();
</pre>
<p>get the <tt class="docutils literal">error_category</tt> for bdecode errors</p>
<a name="error_code_enum"></a></div>
<div class="section" id="enum-error-code-enum">
<h2>enum error_code_enum</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/lazy_entry.hpp">libtorrent/lazy_entry.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="8%" />
<col width="72%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>no_error</td>
<td>0</td>
<td>Not an error</td>
</tr>
<tr><td>expected_string</td>
<td>1</td>
<td>expected string in bencoded string</td>
</tr>
<tr><td>expected_colon</td>
<td>2</td>
<td>expected colon in bencoded string</td>
</tr>
<tr><td>unexpected_eof</td>
<td>3</td>
<td>unexpected end of file in bencoded string</td>
</tr>
<tr><td>expected_value</td>
<td>4</td>
<td>expected value (list, dict, int or string) in bencoded string</td>
</tr>
<tr><td>depth_exceeded</td>
<td>5</td>
<td>bencoded recursion depth limit exceeded</td>
</tr>
<tr><td>limit_exceeded</td>
<td>6</td>
<td>bencoded item count limit exceeded</td>
</tr>
<tr><td>error_code_max</td>
<td>7</td>
<td>the number of error codes</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

3408
docs/reference-Core.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,437 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Create Torrents</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="create-torrents">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Create Torrents</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#create-torrent" id="id22">create_torrent</a></li>
</ul>
</div>
<p>This section describes the functions and classes that are used
to create torrent files. It is a layered API with low level classes
and higher level convenience functions. A torrent is created in 4
steps:</p>
<ol class="arabic simple">
<li>first the files that will be part of the torrent are determined.</li>
<li>the torrent properties are set, such as tracker url, web seeds,
DHT nodes etc.</li>
<li>Read through all the files in the torrent, SHA-1 all the data
and set the piece hashes.</li>
<li>The torrent is bencoded into a file or buffer.</li>
</ol>
<p>If there are a lot of files and or deep directoy hierarchies to
traverse, step one can be time consuming.</p>
<p>Typically step 3 is by far the most time consuming step, since it
requires to read all the bytes from all the files in the torrent.</p>
<p>All of these classes and functions are declared by including
<tt class="docutils literal">libtorrent/create_torrent.hpp</tt>.</p>
<p>example:</p>
<pre class="literal-block">
file_storage fs;
// recursively adds files in directories
add_files(fs, &quot;./my_torrent&quot;);
create_torrent t(fs);
t.add_tracker(&quot;http://my.tracker.com/announce&quot;);
t.set_creator(&quot;libtorrent example&quot;);
// reads the files and calculates the hashes
set_piece_hashes(t, &quot;.&quot;);
ofstream out(&quot;my_torrent.torrent&quot;, std::ios_base::binary);
bencode(std::ostream_iterator&lt;char&gt;(out), t.generate());
</pre>
<a name="create_torrent"></a><div class="section" id="create-torrent">
<h1>create_torrent</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/create_torrent.hpp">libtorrent/create_torrent.hpp</a>&quot;</p>
<p>This class holds state for creating a torrent. After having added
all information to it, call <a class="reference external" href="reference-Create_Torrents.html#generate()">create_torrent::generate()</a> to generate
the torrent. The <a class="reference external" href="reference-Bencoding.html#entry">entry</a> that's returned can then be bencoded into a
.torrent file using <a class="reference external" href="reference-Bencoding.html#bencode()">bencode()</a>.</p>
<pre class="literal-block">
struct create_torrent
{
<strong>create_torrent</strong> (torrent_info const&amp; ti);
<strong>create_torrent</strong> (file_storage&amp; fs, int piece_size = 0
, int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000);
entry <strong>generate</strong> () const;
file_storage const&amp; <strong>files</strong> () const;
void <strong>set_comment</strong> (char const* str);
void <strong>set_creator</strong> (char const* str);
void <strong>set_hash</strong> (int index, sha1_hash const&amp; h);
void <strong>set_file_hash</strong> (int index, sha1_hash const&amp; h);
void <strong>add_url_seed</strong> (std::string const&amp; url);
void <strong>add_http_seed</strong> (std::string const&amp; url);
void <strong>add_node</strong> (std::pair&lt;std::string, int&gt; const&amp; node);
void <strong>add_tracker</strong> (std::string const&amp; url, int tier = 0);
void <strong>set_root_cert</strong> (std::string const&amp; pem);
bool <strong>priv</strong> () const;
void <strong>set_priv</strong> (bool p);
int <strong>num_pieces</strong> () const;
int <strong>piece_length</strong> () const;
int <strong>piece_size</strong> (int i) const;
std::vector&lt;sha1_hash&gt; const&amp; <strong>merkle_tree</strong> () const;
enum flags_t
{
optimize,
merkle,
modification_time,
symlinks,
calculate_file_hashes,
};
};
</pre>
<a name="create_torrent()"></a><div class="section" id="id5">
<h2>create_torrent()</h2>
<pre class="literal-block">
<strong>create_torrent</strong> (torrent_info const&amp; ti);
<strong>create_torrent</strong> (file_storage&amp; fs, int piece_size = 0
, int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000);
</pre>
<p>The <tt class="docutils literal">piece_size</tt> is the size of each piece in bytes. It must
be a multiple of 16 kiB. If a piece size of 0 is specified, a
piece_size will be calculated such that the torrent file is roughly 40 kB.</p>
<p>If a <tt class="docutils literal">pad_size_limit</tt> is specified (other than -1), any file larger than
the specified number of bytes will be preceeded by a pad file to align it
with the start of a piece. The pad_file_limit is ignored unless the
<tt class="docutils literal">optimize</tt> flag is passed. Typically it doesn't make sense to set this
any lower than 4kiB.</p>
<p>The overload that takes a <tt class="docutils literal">torrent_info</tt> object will make a verbatim
copy of its info dictionary (to preserve the info-hash). The copy of
the info dictionary will be used by <a class="reference external" href="reference-Create_Torrents.html#generate()">create_torrent::generate()</a>. This means
that none of the member functions of <a class="reference external" href="reference-Create_Torrents.html#create_torrent">create_torrent</a> that affects
the content of the info dictionary (such as <tt class="docutils literal">set_hash()</tt>), will
have any affect.</p>
<p>The <tt class="docutils literal">flags</tt> arguments specifies options for the torrent creation. It can
be any combination of the flags defined by <a class="reference external" href="reference-Create_Torrents.html#flags_t">create_torrent::flags_t</a>.</p>
<p><tt class="docutils literal">alignment</tt> is used when pad files are enabled. This is the size eligible
files are aligned to. The default is the default bittorrent block size of
16 kiB. It is common to align to the piece size of the torrent.</p>
<a name="generate()"></a></div>
<div class="section" id="generate">
<h2>generate()</h2>
<pre class="literal-block">
entry <strong>generate</strong> () const;
</pre>
<p>This function will generate the .torrent file as a bencode tree. In order to
generate the flat file, use the <a class="reference external" href="reference-Bencoding.html#bencode()">bencode()</a> function.</p>
<p>It may be useful to add custom entries to the torrent file before bencoding it
and saving it to disk.</p>
<p>If anything goes wrong during torrent generation, this function will return
an empty <tt class="docutils literal">entry</tt> structure. You can test for this condition by querying the
type of the entry:</p>
<pre class="literal-block">
file_storage fs;
// add file ...
create_torrent t(fs);
// add trackers and piece hashes ...
e = t.generate();
if (e.type() == entry::undefined_t)
{
// something went wrong
}
</pre>
<p>For instance, you cannot generate a torrent with 0 files in it. If you don't add
any files to the <tt class="docutils literal">file_storage</tt>, torrent generation will fail.</p>
<a name="files()"></a></div>
<div class="section" id="files">
<h2>files()</h2>
<pre class="literal-block">
file_storage const&amp; <strong>files</strong> () const;
</pre>
<p>returns an immutable reference to the <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a> used to create
the torrent from.</p>
<a name="set_comment()"></a></div>
<div class="section" id="set-comment">
<h2>set_comment()</h2>
<pre class="literal-block">
void <strong>set_comment</strong> (char const* str);
</pre>
<p>Sets the comment for the torrent. The string <tt class="docutils literal">str</tt> should be utf-8 encoded.
The comment in a torrent file is optional.</p>
<a name="set_creator()"></a></div>
<div class="section" id="set-creator">
<h2>set_creator()</h2>
<pre class="literal-block">
void <strong>set_creator</strong> (char const* str);
</pre>
<p>Sets the creator of the torrent. The string <tt class="docutils literal">str</tt> should be utf-8 encoded.
This is optional.</p>
<a name="set_hash()"></a></div>
<div class="section" id="set-hash">
<h2>set_hash()</h2>
<pre class="literal-block">
void <strong>set_hash</strong> (int index, sha1_hash const&amp; h);
</pre>
<p>This sets the SHA-1 hash for the specified piece (<tt class="docutils literal">index</tt>). You are required
to set the hash for every piece in the torrent before generating it. If you have
the files on disk, you can use the high level convenience function to do this.
See <a class="reference external" href="reference-Create_Torrents.html#set_piece_hashes()">set_piece_hashes()</a>.</p>
<a name="set_file_hash()"></a></div>
<div class="section" id="set-file-hash">
<h2>set_file_hash()</h2>
<pre class="literal-block">
void <strong>set_file_hash</strong> (int index, sha1_hash const&amp; h);
</pre>
<p>This sets the sha1 hash for this file. This hash will end up under the key <tt class="docutils literal">sha1</tt>
associated with this file (for multi-file torrents) or in the root info dictionary
for single-file torrents.</p>
<a name="add_url_seed()"></a>
<a name="add_http_seed()"></a></div>
<div class="section" id="add-url-seed-add-http-seed">
<h2>add_url_seed() add_http_seed()</h2>
<pre class="literal-block">
void <strong>add_url_seed</strong> (std::string const&amp; url);
void <strong>add_http_seed</strong> (std::string const&amp; url);
</pre>
<p>This adds a url seed to the torrent. You can have any number of url seeds. For a
single file torrent, this should be an HTTP url, pointing to a file with identical
content as the file of the torrent. For a multi-file torrent, it should point to
a directory containing a directory with the same name as this torrent, and all the
files of the torrent in it.</p>
<p>The second function, <tt class="docutils literal">add_http_seed()</tt> adds an HTTP seed instead.</p>
<a name="add_node()"></a></div>
<div class="section" id="add-node">
<h2>add_node()</h2>
<pre class="literal-block">
void <strong>add_node</strong> (std::pair&lt;std::string, int&gt; const&amp; node);
</pre>
<p>This adds a DHT node to the torrent. This especially useful if you're creating a
tracker less torrent. It can be used by clients to bootstrap their DHT node from.
The node is a hostname and a port number where there is a DHT node running.
You can have any number of DHT nodes in a torrent.</p>
<a name="add_tracker()"></a></div>
<div class="section" id="add-tracker">
<h2>add_tracker()</h2>
<pre class="literal-block">
void <strong>add_tracker</strong> (std::string const&amp; url, int tier = 0);
</pre>
<p>Adds a tracker to the torrent. This is not strictly required, but most torrents
use a tracker as their main source of peers. The url should be an <a class="reference external" href="http://">http://</a> or udp://
url to a machine running a bittorrent tracker that accepts announces for this torrent's
info-hash. The tier is the fallback priority of the tracker. All trackers with tier 0 are
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
fail, trackers with tier 2 are tried, and so on.</p>
<a name="set_root_cert()"></a></div>
<div class="section" id="set-root-cert">
<h2>set_root_cert()</h2>
<pre class="literal-block">
void <strong>set_root_cert</strong> (std::string const&amp; pem);
</pre>
<p>This function sets an X.509 certificate in PEM format to the torrent. This makes the
torrent an <em>SSL torrent</em>. An SSL torrent requires that each peer has a valid certificate
signed by this root certificate. For SSL torrents, all peers are connecting over SSL
connections. For more information, see the section on <a class="reference external" href="manual-ref.html#ssl-torrents">ssl torrents</a>.</p>
<p>The string is not the path to the cert, it's the actual content of the certificate,
loaded into a std::string.</p>
<a name="priv()"></a>
<a name="set_priv()"></a></div>
<div class="section" id="priv-set-priv">
<h2>priv() set_priv()</h2>
<pre class="literal-block">
bool <strong>priv</strong> () const;
void <strong>set_priv</strong> (bool p);
</pre>
<p>Sets and queries the private flag of the torrent.
Torrents with the private flag set ask clients to not use any other
sources than the tracker for peers, and to not advertize itself publicly,
apart from the tracker.</p>
<a name="num_pieces()"></a></div>
<div class="section" id="num-pieces">
<h2>num_pieces()</h2>
<pre class="literal-block">
int <strong>num_pieces</strong> () const;
</pre>
<p>returns the number of pieces in the associated <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a> object.</p>
<a name="piece_length()"></a>
<a name="piece_size()"></a></div>
<div class="section" id="piece-length-piece-size">
<h2>piece_length() piece_size()</h2>
<pre class="literal-block">
int <strong>piece_length</strong> () const;
int <strong>piece_size</strong> (int i) const;
</pre>
<p><tt class="docutils literal">piece_length()</tt> returns the piece size of all pieces but the
last one. <tt class="docutils literal">piece_size()</tt> returns the size of the specified piece.
these functions are just forwarding to the associated <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a>.</p>
<a name="merkle_tree()"></a></div>
<div class="section" id="merkle-tree">
<h2>merkle_tree()</h2>
<pre class="literal-block">
std::vector&lt;sha1_hash&gt; const&amp; <strong>merkle_tree</strong> () const;
</pre>
<p>This function returns the merkle hash tree, if the torrent was created as a merkle
torrent. The tree is created by <tt class="docutils literal">generate()</tt> and won't be valid until that function
has been called. When creating a merkle tree torrent, the actual tree itself has to
be saved off separately and fed into libtorrent the first time you start seeding it,
through the <tt class="docutils literal"><span class="pre">torrent_info::set_merkle_tree()</span></tt> function. From that point onwards, the
tree will be saved in the resume data.</p>
<a name="flags_t"></a></div>
<div class="section" id="enum-flags-t">
<h2>enum flags_t</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/create_torrent.hpp">libtorrent/create_torrent.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="21%" />
<col width="6%" />
<col width="72%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>optimize</td>
<td>1</td>
<td>This will insert pad files to align the files to piece boundaries, for
optimized disk-I/O.</td>
</tr>
<tr><td>merkle</td>
<td>2</td>
<td>This will create a merkle hash tree torrent. A merkle torrent cannot
be opened in clients that don't specifically support merkle torrents.
The benefit is that the resulting torrent file will be much smaller and
not grow with more pieces. When this option is specified, it is
recommended to have a fairly small piece size, say 64 kiB.
When creating merkle torrents, the full hash tree is also generated
and should be saved off separately. It is accessed through the
<a class="reference external" href="reference-Create_Torrents.html#merkle_tree()">create_torrent::merkle_tree()</a> function.</td>
</tr>
<tr><td>modification_time</td>
<td>4</td>
<td>This will include the file modification time as part of the torrent.
This is not enabled by default, as it might cause problems when you
create a torrent from separate files with the same content, hoping to
yield the same info-hash. If the files have different modification times,
with this option enabled, you would get different info-hashes for the
files.</td>
</tr>
<tr><td>symlinks</td>
<td>8</td>
<td>If this flag is set, files that are symlinks get a symlink attribute
set on them and their data will not be included in the torrent. This
is useful if you need to reconstruct a file hierarchy which contains
symlinks.</td>
</tr>
<tr><td>calculate_file_hashes</td>
<td>16</td>
<td>If this is set, the <a class="reference external" href="reference-Create_Torrents.html#set_piece_hashes()">set_piece_hashes()</a> function will, as it calculates
the piece hashes, also calculate the file hashes and add those associated
with each file. Note that unless you use the <a class="reference external" href="reference-Create_Torrents.html#set_piece_hashes()">set_piece_hashes()</a> function,
this flag will have no effect.</td>
</tr>
</tbody>
</table>
<a name="add_files()"></a></div>
<div class="section" id="add-files">
<h2>add_files()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/create_torrent.hpp">libtorrent/create_torrent.hpp</a>&quot;</p>
<pre class="literal-block">
template &lt;class Pred&gt; void <strong>add_files</strong> (file_storage&amp; fs, std::string const&amp; file, Pred p, boost::uint32_t flags = 0);
inline void <strong>add_files</strong> (file_storage&amp; fs, std::string const&amp; file, boost::uint32_t flags = 0);
</pre>
<p>Adds the file specified by <tt class="docutils literal">path</tt> to the <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a> object. In case <tt class="docutils literal">path</tt>
refers to a diretory, files will be added recursively from the directory.</p>
<p>If specified, the predicate <tt class="docutils literal">p</tt> is called once for every file and directory that
is encountered. files for which <tt class="docutils literal">p</tt> returns true are added, and directories for
which <tt class="docutils literal">p</tt> returns true are traversed. <tt class="docutils literal">p</tt> must have the following signature:</p>
<pre class="literal-block">
bool Pred(std::string const&amp; p);
</pre>
<p>The path that is passed in to the predicate is the full path of the file or
directory. If no predicate is specified, all files are added, and all directories
are traveresed.</p>
<p>The &quot;..&quot; directory is never traversed.</p>
<p>The <tt class="docutils literal">flags</tt> argument should be the same as the flags passed to the <a class="reference internal" href="#create-torrent">create_torrent</a>
constructor.</p>
<a name="set_piece_hashes()"></a></div>
<div class="section" id="set-piece-hashes">
<h2>set_piece_hashes()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/create_torrent.hpp">libtorrent/create_torrent.hpp</a>&quot;</p>
<pre class="literal-block">
void <strong>set_piece_hashes</strong> (create_torrent&amp; t, std::string const&amp; p
, boost::function&lt;void(int)&gt; f, error_code&amp; ec);
inline void <strong>set_piece_hashes</strong> (create_torrent&amp; t, std::string const&amp; p);
inline void <strong>set_piece_hashes</strong> (create_torrent&amp; t, std::string const&amp; p, error_code&amp; ec);
</pre>
<p>This function will assume that the files added to the torrent file exists at path
<tt class="docutils literal">p</tt>, read those files and hash the content and set the hashes in the <tt class="docutils literal">create_torrent</tt>
object. The optional function <tt class="docutils literal">f</tt> is called in between every hash that is set. <tt class="docutils literal">f</tt>
must have the following signature:</p>
<pre class="literal-block">
void Fun(int);
</pre>
<p>The overloads that don't take an <tt class="docutils literal">error_code&amp;</tt> may throw an exception in case of a
file error, the other overloads sets the error code to reflect the error, if any.</p>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

View File

@ -0,0 +1,576 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Custom Storage</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="custom-storage">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Custom Storage</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#file-pool" id="id12">file_pool</a></li>
<li><a class="reference internal" href="#storage-interface" id="id13">storage_interface</a></li>
<li><a class="reference internal" href="#default-storage" id="id14">default_storage</a></li>
</ul>
</div>
<p>This is an example storage implementation that stores all pieces in a <tt class="docutils literal"><span class="pre">std::map</span></tt>,
i.e. in RAM. It's not necessarily very useful in practice, but illustrates the
basics of implementing a custom storage.</p>
<pre class="literal-block">
struct temp_storage : storage_interface
{
temp_storage(file_storage const&amp; fs) : m_files(fs) {}
virtual bool initialize(bool allocate_files) { return false; }
virtual bool has_any_file() { return false; }
virtual int read(char* buf, int slot, int offset, int size)
{
std::map&lt;int, std::vector&lt;char&gt; &gt;::const_iterator i = m_file_data.find(slot);
if (i == m_file_data.end()) return 0;
int available = i-&gt;second.size() - offset;
if (available &lt;= 0) return 0;
if (available &gt; size) available = size;
memcpy(buf, &amp;i-&gt;second[offset], available);
return available;
}
virtual int write(const char* buf, int slot, int offset, int size)
{
std::vector&lt;char&gt;&amp; data = m_file_data[slot];
if (data.size() &lt; offset + size) data.resize(offset + size);
std::memcpy(&amp;data[offset], buf, size);
return size;
}
virtual bool rename_file(int file, std::string const&amp; new_name)
{ assert(false); return false; }
virtual bool move_storage(std::string const&amp; save_path) { return false; }
virtual bool verify_resume_data(lazy_entry const&amp; rd, error_code&amp; error) { return false; }
virtual bool write_resume_data(entry&amp; rd) const { return false; }
virtual bool move_slot(int src_slot, int dst_slot) { assert(false); return false; }
virtual bool swap_slots(int slot1, int slot2) { assert(false); return false; }
virtual bool swap_slots3(int slot1, int slot2, int slot3) { assert(false); return false; }
virtual size_type physical_offset(int slot, int offset)
{ return slot * m_files.piece_length() + offset; };
virtual sha1_hash hash_for_slot(int slot, partial_hash&amp; ph, int piece_size)
{
int left = piece_size - ph.offset;
assert(left &gt;= 0);
if (left &gt; 0)
{
std::vector&lt;char&gt;&amp; data = m_file_data[slot];
// if there are padding files, those blocks will be considered
// completed even though they haven't been written to the storage.
// in this case, just extend the piece buffer to its full size
// and fill it with zeroes.
if (data.size() &lt; piece_size) data.resize(piece_size, 0);
ph.h.update(&amp;data[ph.offset], left);
}
return ph.h.final();
}
virtual bool release_files() { return false; }
virtual bool delete_files() { return false; }
std::map&lt;int, std::vector&lt;char&gt; &gt; m_file_data;
file_storage m_files;
};
storage_interface* temp_storage_constructor(
file_storage const&amp; fs, file_storage const* mapped
, std::string const&amp; path, file_pool&amp; fp
, std::vector&lt;boost::uint8_t&gt; const&amp; prio)
{
return new temp_storage(fs);
}
</pre>
<a name="file_pool"></a><div class="section" id="file-pool">
<h1>file_pool</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/file_pool.hpp">libtorrent/file_pool.hpp</a>&quot;</p>
<p>this is an internal cache of open file handles. It's primarily used by
<a class="reference external" href="reference-Custom_Storage.html#storage_interface">storage_interface</a> implementations. It provides semi weak guarantees of
not opening more file handles than specified. Given multiple threads,
each with the ability to lock a file handle (via smart pointer), there
may be windows where more file handles are open.</p>
<pre class="literal-block">
struct file_pool : boost::noncopyable
{
<strong>~file_pool</strong> ();
<strong>file_pool</strong> (int size = 40);
boost::intrusive_ptr&lt;file&gt; <strong>open_file</strong> (void* st, std::string const&amp; p
, int file_index, file_storage const&amp; fs, int m, error_code&amp; ec);
void <strong>release</strong> (void* st);
void <strong>release</strong> (void* st, int file_index);
void <strong>resize</strong> (int size);
int <strong>size_limit</strong> () const;
};
</pre>
<a name="~file_pool()"></a>
<a name="file_pool()"></a><div class="section" id="file-pool-file-pool">
<h2>~file_pool() file_pool()</h2>
<pre class="literal-block">
<strong>~file_pool</strong> ();
<strong>file_pool</strong> (int size = 40);
</pre>
<p><tt class="docutils literal">size</tt> specifies the number of allowed files handles
to hold open at any given time.</p>
<a name="open_file()"></a></div>
<div class="section" id="open-file">
<h2>open_file()</h2>
<pre class="literal-block">
boost::intrusive_ptr&lt;file&gt; <strong>open_file</strong> (void* st, std::string const&amp; p
, int file_index, file_storage const&amp; fs, int m, error_code&amp; ec);
</pre>
<p>return an open file handle to file at <tt class="docutils literal">file_index</tt> in the
<a class="reference external" href="reference-Storage.html#file_storage">file_storage</a> <tt class="docutils literal">fs</tt> opened at save path <tt class="docutils literal">p</tt>. <tt class="docutils literal">m</tt> is the
file open mode (see <a class="reference external" href="file::open_mode_t">file::open_mode_t</a>).</p>
<a name="release()"></a></div>
<div class="section" id="release">
<h2>release()</h2>
<pre class="literal-block">
void <strong>release</strong> (void* st);
void <strong>release</strong> (void* st, int file_index);
</pre>
<p>release all files belonging to the specified <a class="reference external" href="reference-Custom_Storage.html#storage_interface">storage_interface</a> (<tt class="docutils literal">st</tt>)
the overload that takes <tt class="docutils literal">file_index</tt> releases only the file with
that index in storage <tt class="docutils literal">st</tt>.</p>
<a name="resize()"></a></div>
<div class="section" id="resize">
<h2>resize()</h2>
<pre class="literal-block">
void <strong>resize</strong> (int size);
</pre>
<p>update the allowed number of open file handles to <tt class="docutils literal">size</tt>.</p>
<a name="size_limit()"></a></div>
<div class="section" id="size-limit">
<h2>size_limit()</h2>
<pre class="literal-block">
int <strong>size_limit</strong> () const;
</pre>
<p>returns the current limit of number of allowed open file handles held
by the <a class="reference external" href="reference-Custom_Storage.html#file_pool">file_pool</a>.</p>
<a name="storage_interface"></a></div>
</div>
<div class="section" id="storage-interface">
<h1>storage_interface</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/storage.hpp">libtorrent/storage.hpp</a>&quot;</p>
<p>The storage interface is a pure virtual class that can be implemented to
customize how and where data for a torrent is stored. The default storage
implementation uses regular files in the filesystem, mapping the files in the
torrent in the way one would assume a torrent is saved to disk. Implementing
your own storage interface makes it possible to store all data in RAM, or in
some optimized order on disk (the order the pieces are received for instance),
or saving multifile torrents in a single file in order to be able to take
advantage of optimized disk-I/O.</p>
<p>It is also possible to write a thin class that uses the default storage but
modifies some particular behavior, for instance encrypting the data before
it's written to disk, and decrypting it when it's read again.</p>
<p>The storage interface is based on slots, each slot is 'piece_size' number
of bytes. All access is done by writing and reading whole or partial
slots. One slot is one piece in the torrent, but the data in the slot
does not necessarily correspond to the piece with the same index (in
compact allocation mode it won't).</p>
<p>libtorrent comes with two built-in storage implementations; <tt class="docutils literal">default_storage</tt>
and <tt class="docutils literal">disabled_storage</tt>. Their constructor functions are called <a class="reference external" href="reference-Storage.html#default_storage_constructor()">default_storage_constructor()</a>
and <tt class="docutils literal">disabled_storage_constructor</tt> respectively. The disabled storage does
just what it sounds like. It throws away data that's written, and it
reads garbage. It's useful mostly for benchmarking and profiling purpose.</p>
<pre class="literal-block">
struct storage_interface
{
virtual bool <strong>initialize</strong> (bool allocate_files) = 0;
virtual bool <strong>has_any_file</strong> () = 0;
virtual int <strong>writev</strong> (<a class="reference external" href="file::iovec_t">file::iovec_t</a> const* bufs, int slot, int offset, int num_bufs, int flags = <a class="reference external" href="file::random_access">file::random_access</a>);
virtual int <strong>readv</strong> (<a class="reference external" href="file::iovec_t">file::iovec_t</a> const* bufs, int slot, int offset, int num_bufs, int flags = <a class="reference external" href="file::random_access">file::random_access</a>);
virtual void <strong>hint_read</strong> (int, int, int);
virtual int <strong>read</strong> (char* buf, int slot, int offset, int size) = 0;
virtual int <strong>write</strong> (const char* buf, int slot, int offset, int size) = 0;
virtual size_type <strong>physical_offset</strong> (int slot, int offset) = 0;
virtual int <strong>sparse_end</strong> (int start) const;
virtual int <strong>move_storage</strong> (std::string const&amp; save_path, int flags) = 0;
virtual bool <strong>verify_resume_data</strong> (lazy_entry const&amp; rd, error_code&amp; error) = 0;
virtual bool <strong>write_resume_data</strong> (entry&amp; rd) const = 0;
virtual bool <strong>move_slot</strong> (int src_slot, int dst_slot) = 0;
virtual bool <strong>swap_slots</strong> (int slot1, int slot2) = 0;
virtual bool <strong>swap_slots3</strong> (int slot1, int slot2, int slot3) = 0;
virtual bool <strong>release_files</strong> () = 0;
virtual bool <strong>rename_file</strong> (int index, std::string const&amp; new_filename) = 0;
virtual bool <strong>delete_files</strong> () = 0;
disk_buffer_pool* <strong>disk_pool</strong> ();
session_settings const&amp; <strong>settings</strong> () const;
void <strong>set_error</strong> (std::string const&amp; file, error_code const&amp; ec) const;
error_code const&amp; <strong>error</strong> () const;
std::string const&amp; <strong>error_file</strong> () const;
virtual void <strong>clear_error</strong> ();
};
</pre>
<a name="initialize()"></a><div class="section" id="initialize">
<h2>initialize()</h2>
<pre class="literal-block">
virtual bool <strong>initialize</strong> (bool allocate_files) = 0;
</pre>
<p>This function is called when the storage is to be initialized. The default storage
will create directories and empty files at this point. If <tt class="docutils literal">allocate_files</tt> is true,
it will also <tt class="docutils literal">ftruncate</tt> all files to their target size.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<a name="has_any_file()"></a></div>
<div class="section" id="has-any-file">
<h2>has_any_file()</h2>
<pre class="literal-block">
virtual bool <strong>has_any_file</strong> () = 0;
</pre>
<p>This function is called when first checking (or re-checking) the storage for a torrent.
It should return true if any of the files that is used in this storage exists on disk.
If so, the storage will be checked for existing pieces before starting the download.</p>
<a name="writev()"></a>
<a name="readv()"></a></div>
<div class="section" id="writev-readv">
<h2>writev() readv()</h2>
<pre class="literal-block">
virtual int <strong>writev</strong> (<a class="reference external" href="file::iovec_t">file::iovec_t</a> const* bufs, int slot, int offset, int num_bufs, int flags = <a class="reference external" href="file::random_access">file::random_access</a>);
virtual int <strong>readv</strong> (<a class="reference external" href="file::iovec_t">file::iovec_t</a> const* bufs, int slot, int offset, int num_bufs, int flags = <a class="reference external" href="file::random_access">file::random_access</a>);
</pre>
<p>These functions should read or write the data in or to the given <tt class="docutils literal">slot</tt> at the given <tt class="docutils literal">offset</tt>.
It should read or write <tt class="docutils literal">num_bufs</tt> buffers sequentially, where the size of each buffer
is specified in the buffer array <tt class="docutils literal">bufs</tt>. The <a class="reference external" href="file::iovec_t">file::iovec_t</a> type has the following members:</p>
<pre class="literal-block">
struct iovec_t
{
void* iov_base;
size_t iov_len;
};
</pre>
<p>The return value is the number of bytes actually read or written, or -1 on failure. If
it returns -1, the error code is expected to be set to</p>
<p>Every buffer in <tt class="docutils literal">bufs</tt> can be assumed to be page aligned and be of a page aligned size,
except for the last buffer of the torrent. The allocated buffer can be assumed to fit a
fully page aligned number of bytes though. This is useful when reading and writing the
last piece of a file in unbuffered mode.</p>
<p>The <tt class="docutils literal">offset</tt> is aligned to 16 kiB boundries <em>most of the time</em>, but there are rare
exceptions when it's not. Specifically if the read cache is disabled/or full and a
client requests unaligned data, or the file itself is not aligned in the torrent.
Most clients request aligned data.</p>
<a name="hint_read()"></a></div>
<div class="section" id="hint-read">
<h2>hint_read()</h2>
<pre class="literal-block">
virtual void <strong>hint_read</strong> (int, int, int);
</pre>
<p>This function is called when a read job is queued. It gives the storage wrapper an
opportunity to hint the operating system about this coming read. For instance, the
storage may call <tt class="docutils literal">posix_fadvise(POSIX_FADV_WILLNEED)</tt> or <tt class="docutils literal">fcntl(F_RDADVISE)</tt>.</p>
<a name="read()"></a></div>
<div class="section" id="read">
<h2>read()</h2>
<pre class="literal-block">
virtual int <strong>read</strong> (char* buf, int slot, int offset, int size) = 0;
</pre>
<p>negative return value indicates an error</p>
<a name="write()"></a></div>
<div class="section" id="write">
<h2>write()</h2>
<pre class="literal-block">
virtual int <strong>write</strong> (const char* buf, int slot, int offset, int size) = 0;
</pre>
<p>negative return value indicates an error</p>
<a name="physical_offset()"></a></div>
<div class="section" id="physical-offset">
<h2>physical_offset()</h2>
<pre class="literal-block">
virtual size_type <strong>physical_offset</strong> (int slot, int offset) = 0;
</pre>
<p>returns the offset on the physical storage medium for the
byte at offset <tt class="docutils literal">offset</tt> in slot <tt class="docutils literal">slot</tt>.</p>
<a name="sparse_end()"></a></div>
<div class="section" id="sparse-end">
<h2>sparse_end()</h2>
<pre class="literal-block">
virtual int <strong>sparse_end</strong> (int start) const;
</pre>
<p>This function is optional. It is supposed to return the first piece, starting at
<tt class="docutils literal">start</tt> that is fully contained within a data-region on disk (i.e. non-sparse
region). The purpose of this is to skip parts of files that can be known to contain
zeros when checking files.</p>
<a name="move_storage()"></a></div>
<div class="section" id="move-storage">
<h2>move_storage()</h2>
<pre class="literal-block">
virtual int <strong>move_storage</strong> (std::string const&amp; save_path, int flags) = 0;
</pre>
<p>This function should move all the files belonging to the storage to the new save_path.
The default storage moves the single file or the directory of the torrent.</p>
<p>Before moving the files, any open file handles may have to be closed, like
<tt class="docutils literal">release_files()</tt>.</p>
<p>returns one of:
| no_error = 0
| need_full_check = -1
| fatal_disk_error = -2
| file_exist = -4</p>
<a name="verify_resume_data()"></a></div>
<div class="section" id="verify-resume-data">
<h2>verify_resume_data()</h2>
<pre class="literal-block">
virtual bool <strong>verify_resume_data</strong> (lazy_entry const&amp; rd, error_code&amp; error) = 0;
</pre>
<p>This function should verify the resume data <tt class="docutils literal">rd</tt> with the files
on disk. If the resume data seems to be up-to-date, return true. If
not, set <tt class="docutils literal">error</tt> to a description of what mismatched and return false.</p>
<p>The default storage may compare file sizes and time stamps of the files.</p>
<p>Returning <tt class="docutils literal">false</tt> indicates an error occurred.</p>
<a name="write_resume_data()"></a></div>
<div class="section" id="write-resume-data">
<h2>write_resume_data()</h2>
<pre class="literal-block">
virtual bool <strong>write_resume_data</strong> (entry&amp; rd) const = 0;
</pre>
<p>This function should fill in resume data, the current state of the
storage, in <tt class="docutils literal">rd</tt>. The default storage adds file timestamps and
sizes.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<a name="move_slot()"></a></div>
<div class="section" id="move-slot">
<h2>move_slot()</h2>
<pre class="literal-block">
virtual bool <strong>move_slot</strong> (int src_slot, int dst_slot) = 0;
</pre>
<p>This function should copy or move the data in slot <tt class="docutils literal">src_slot</tt> to
the slot <tt class="docutils literal">dst_slot</tt>. This is only used in compact mode.</p>
<p>If the storage caches slots, this could be implemented more
efficient than reading and writing the data.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<a name="swap_slots()"></a></div>
<div class="section" id="swap-slots">
<h2>swap_slots()</h2>
<pre class="literal-block">
virtual bool <strong>swap_slots</strong> (int slot1, int slot2) = 0;
</pre>
<p>This function should swap the data in <tt class="docutils literal">slot1</tt> and <tt class="docutils literal">slot2</tt>. The default
storage uses a scratch buffer to read the data into, then moving the other
slot and finally writing back the temporary slot's data</p>
<p>This is only used in compact mode.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<a name="swap_slots3()"></a></div>
<div class="section" id="swap-slots3">
<h2>swap_slots3()</h2>
<pre class="literal-block">
virtual bool <strong>swap_slots3</strong> (int slot1, int slot2, int slot3) = 0;
</pre>
<p>This function should do a 3-way swap, or shift of the slots. <tt class="docutils literal">slot1</tt>
should move to <tt class="docutils literal">slot2</tt>, which should be moved to <tt class="docutils literal">slot3</tt> which in turn
should be moved to <tt class="docutils literal">slot1</tt>.</p>
<p>This is only used in compact mode.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<a name="release_files()"></a></div>
<div class="section" id="release-files">
<h2>release_files()</h2>
<pre class="literal-block">
virtual bool <strong>release_files</strong> () = 0;
</pre>
<p>This function should release all the file handles that it keeps open to files
belonging to this storage. The default implementation just calls
<tt class="docutils literal"><span class="pre">file_pool::release_files(this)</span></tt>.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<a name="rename_file()"></a></div>
<div class="section" id="rename-file">
<h2>rename_file()</h2>
<pre class="literal-block">
virtual bool <strong>rename_file</strong> (int index, std::string const&amp; new_filename) = 0;
</pre>
<p>Rename file with index <tt class="docutils literal">file</tt> to the thame <tt class="docutils literal">new_name</tt>. If there is an error,
<tt class="docutils literal">true</tt> should be returned.</p>
<a name="delete_files()"></a></div>
<div class="section" id="delete-files">
<h2>delete_files()</h2>
<pre class="literal-block">
virtual bool <strong>delete_files</strong> () = 0;
</pre>
<p>This function should delete all files and directories belonging to this storage.</p>
<p>Returning <tt class="docutils literal">true</tt> indicates an error occurred.</p>
<p>The <tt class="docutils literal">disk_buffer_pool</tt> is used to allocate and free disk buffers. It has the
following members:</p>
<pre class="literal-block">
struct disk_buffer_pool : boost::noncopyable
{
char* allocate_buffer(char const* category);
void free_buffer(char* buf);
char* allocate_buffers(int blocks, char const* category);
void free_buffers(char* buf, int blocks);
int block_size() const { return m_block_size; }
void release_memory();
};
</pre>
<a name="disk_pool()"></a></div>
<div class="section" id="disk-pool">
<h2>disk_pool()</h2>
<pre class="literal-block">
disk_buffer_pool* <strong>disk_pool</strong> ();
</pre>
<p>access global disk_buffer_pool, for allocating and freeing disk buffers</p>
<a name="settings()"></a></div>
<div class="section" id="settings">
<h2>settings()</h2>
<pre class="literal-block">
session_settings const&amp; <strong>settings</strong> () const;
</pre>
<p>access global <a class="reference external" href="reference-Settings.html#session_settings">session_settings</a></p>
<a name="set_error()"></a></div>
<div class="section" id="set-error">
<h2>set_error()</h2>
<pre class="literal-block">
void <strong>set_error</strong> (std::string const&amp; file, error_code const&amp; ec) const;
</pre>
<p>called by the storage implementation to set it into an
error state. Typically whenever a critical file operation
fails.</p>
<a name="error_file()"></a>
<a name="error()"></a></div>
<div class="section" id="error-file-error">
<h2>error_file() error()</h2>
<pre class="literal-block">
error_code const&amp; <strong>error</strong> () const;
std::string const&amp; <strong>error_file</strong> () const;
</pre>
<p>returns the currently set error code and file path associated with it,
if set.</p>
<a name="clear_error()"></a></div>
<div class="section" id="clear-error">
<h2>clear_error()</h2>
<pre class="literal-block">
virtual void <strong>clear_error</strong> ();
</pre>
<p>reset the error state to allow continuing reading and writing
to the storage</p>
<a name="default_storage"></a></div>
</div>
<div class="section" id="default-storage">
<h1>default_storage</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/storage.hpp">libtorrent/storage.hpp</a>&quot;</p>
<p>The default implementation of <a class="reference external" href="reference-Custom_Storage.html#storage_interface">storage_interface</a>. Behaves as a normal bittorrent client.
It is possible to derive from this class in order to override some of its behavior, when
implementing a custom storage.</p>
<pre class="literal-block">
class default_storage : public storage_interface, boost::noncopyable
{
<strong>default_storage</strong> (file_storage const&amp; fs, file_storage const* mapped, std::string const&amp; path
, file_pool&amp; fp, std::vector&lt;boost::uint8_t&gt; const&amp; file_prio);
bool <strong>move_slot</strong> (int src_slot, int dst_slot);
bool <strong>rename_file</strong> (int index, std::string const&amp; new_filename);
int <strong>read</strong> (char* buf, int slot, int offset, int size);
bool <strong>has_any_file</strong> ();
int <strong>move_storage</strong> (std::string const&amp; save_path, int flags);
bool <strong>write_resume_data</strong> (entry&amp; rd) const;
int <strong>write</strong> (char const* buf, int slot, int offset, int size);
int <strong>writev</strong> (<a class="reference external" href="file::iovec_t">file::iovec_t</a> const* buf, int slot, int offset, int num_bufs, int flags = <a class="reference external" href="file::random_access">file::random_access</a>);
size_type <strong>physical_offset</strong> (int slot, int offset);
bool <strong>release_files</strong> ();
bool <strong>delete_files</strong> ();
bool <strong>verify_resume_data</strong> (lazy_entry const&amp; rd, error_code&amp; error);
int <strong>readv</strong> (<a class="reference external" href="file::iovec_t">file::iovec_t</a> const* bufs, int slot, int offset, int num_bufs, int flags = <a class="reference external" href="file::random_access">file::random_access</a>);
bool <strong>swap_slots3</strong> (int slot1, int slot2, int slot3);
bool <strong>initialize</strong> (bool allocate_files);
void <strong>hint_read</strong> (int slot, int offset, int len);
bool <strong>swap_slots</strong> (int slot1, int slot2);
int <strong>sparse_end</strong> (int start) const;
file_storage const&amp; <strong>files</strong> () const;
};
</pre>
<a name="move_flags_t"></a><div class="section" id="enum-move-flags-t">
<h2>enum move_flags_t</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/storage.hpp">libtorrent/storage.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="25%" />
<col width="8%" />
<col width="67%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>always_replace_files</td>
<td>0</td>
<td>replace any files in the destination when copying
or moving the storage</td>
</tr>
<tr><td>fail_if_exist</td>
<td>1</td>
<td>if any files that we want to copy exist in the destination
exist, fail the whole operation and don't perform
any copy or move. There is an inherent race condition
in this mode. The files are checked for existence before
the operation starts. In between the check and performing
the copy, the destination files may be created, in which
case they are replaced.</td>
</tr>
<tr><td>dont_replace</td>
<td>2</td>
<td>if any file exist in the target, take those files instead
of the ones we may have in the source.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

222
docs/reference-Filter.html Normal file
View File

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Filter</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="filter">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Filter</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#ip-filter" id="id10">ip_filter</a></li>
<li><a class="reference internal" href="#port-filter" id="id11">port_filter</a></li>
</ul>
</div>
<a name="ip_filter"></a><div class="section" id="ip-filter">
<h1>ip_filter</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ip_filter.hpp">libtorrent/ip_filter.hpp</a>&quot;</p>
<p>The <tt class="docutils literal">ip_filter</tt> class is a set of rules that uniquely categorizes all
ip addresses as allowed or disallowed. The default constructor creates
a single rule that allows all addresses (0.0.0.0 - 255.255.255.255 for
the IPv4 range, and the equivalent range covering all addresses for the
IPv6 range).</p>
<p>A default constructed <a class="reference external" href="reference-Filter.html#ip_filter">ip_filter</a> does not filter any address.</p>
<pre class="literal-block">
struct ip_filter
{
void <strong>add_rule</strong> (address first, address last, int flags);
int <strong>access</strong> (address const&amp; addr) const;
filter_tuple_t <strong>export_filter</strong> () const;
enum access_flags
{
blocked,
};
};
</pre>
<a name="add_rule()"></a><div class="section" id="add-rule">
<h2>add_rule()</h2>
<pre class="literal-block">
void <strong>add_rule</strong> (address first, address last, int flags);
</pre>
<p>Adds a rule to the filter. <tt class="docutils literal">first</tt> and <tt class="docutils literal">last</tt> defines a range of
ip addresses that will be marked with the given flags. The <tt class="docutils literal">flags</tt>
can currently be 0, which means allowed, or <tt class="docutils literal"><span class="pre">ip_filter::blocked</span></tt>, which
means disallowed.</p>
<p>precondition:
<tt class="docutils literal">first.is_v4() == last.is_v4() &amp;&amp; first.is_v6() == last.is_v6()</tt></p>
<p>postcondition:
<tt class="docutils literal">access(x) == flags</tt> for every <tt class="docutils literal">x</tt> in the range [<tt class="docutils literal">first</tt>, <tt class="docutils literal">last</tt>]</p>
<p>This means that in a case of overlapping ranges, the last one applied takes
precedence.</p>
<a name="access()"></a></div>
<div class="section" id="access">
<h2>access()</h2>
<pre class="literal-block">
int <strong>access</strong> (address const&amp; addr) const;
</pre>
<p>Returns the access permissions for the given address (<tt class="docutils literal">addr</tt>). The permission
can currently be 0 or <tt class="docutils literal"><span class="pre">ip_filter::blocked</span></tt>. The complexity of this operation
is O(<tt class="docutils literal">log</tt> n), where n is the minimum number of non-overlapping ranges to describe
the current filter.</p>
<a name="export_filter()"></a></div>
<div class="section" id="export-filter">
<h2>export_filter()</h2>
<pre class="literal-block">
filter_tuple_t <strong>export_filter</strong> () const;
</pre>
<p>This function will return the current state of the filter in the minimum number of
ranges possible. They are sorted from ranges in low addresses to high addresses. Each
<a class="reference external" href="reference-Bencoding.html#entry">entry</a> in the returned vector is a range with the access control specified in its
<tt class="docutils literal">flags</tt> field.</p>
<p>The return value is a tuple containing two range-lists. One for IPv4 addresses
and one for IPv6 addresses.</p>
<a name="access_flags"></a></div>
<div class="section" id="enum-access-flags">
<h2>enum access_flags</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ip_filter.hpp">libtorrent/ip_filter.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="12%" />
<col width="9%" />
<col width="78%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>blocked</td>
<td>1</td>
<td>indicates that IPs in this range should not be connected
to nor accepted as incoming connections</td>
</tr>
</tbody>
</table>
<a name="port_filter"></a></div>
</div>
<div class="section" id="port-filter">
<h1>port_filter</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ip_filter.hpp">libtorrent/ip_filter.hpp</a>&quot;</p>
<p>the port filter maps non-overlapping port ranges to flags. This
is primarily used to indicate whether a range of ports should
be connected to or not. The default is to have the full port
range (0-65535) set to flag 0.</p>
<pre class="literal-block">
class port_filter
{
void <strong>add_rule</strong> (boost::uint16_t first, boost::uint16_t last, int flags);
int <strong>access</strong> (boost::uint16_t port) const;
enum access_flags
{
blocked,
};
};
</pre>
<a name="add_rule()"></a><div class="section" id="id6">
<h2>add_rule()</h2>
<pre class="literal-block">
void <strong>add_rule</strong> (boost::uint16_t first, boost::uint16_t last, int flags);
</pre>
<p>set the flags for the specified port range (<tt class="docutils literal">first</tt>, <tt class="docutils literal">last</tt>) to
<tt class="docutils literal">flags</tt> overwriting any existing rule for those ports. The range
is inclusive, i.e. the port <tt class="docutils literal">last</tt> also has the flag set on it.</p>
<a name="access()"></a></div>
<div class="section" id="id7">
<h2>access()</h2>
<pre class="literal-block">
int <strong>access</strong> (boost::uint16_t port) const;
</pre>
<p>test the specified port (<tt class="docutils literal">port</tt>) for whether it is blocked
or not. The returned value is the flags set for this port.
see acces_flags.</p>
<a name="access_flags"></a></div>
<div class="section" id="id8">
<h2>enum access_flags</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ip_filter.hpp">libtorrent/ip_filter.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="13%" />
<col width="10%" />
<col width="76%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>blocked</td>
<td>1</td>
<td>this flag indicates that destination ports in the
range should not be connected to</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

603
docs/reference-Plugins.html Normal file
View File

@ -0,0 +1,603 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title></title>
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<div class="section" id="plugins">
<h1>Plugins</h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Author:</th><td class="field-body">Arvid Norberg, <a class="reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td>
</tr>
<tr class="field"><th class="field-name">Version:</th><td class="field-body">1.0.0</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#plugins" id="id66">Plugins</a></li>
<li><a class="reference internal" href="#plugin-interface" id="id67">plugin-interface</a></li>
<li><a class="reference internal" href="#custom-alerts" id="id68">custom alerts</a></li>
</ul>
</div>
<p>libtorrent has a <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> interface for implementing extensions to the protocol.
These can be general extensions for transferring metadata or peer exchange
extensions, or it could be used to provide a way to customize the protocol
to fit a particular (closed) network.</p>
<p>In short, the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> interface makes it possible to:</p>
<ul class="simple">
<li>register extension messages (sent in the extension handshake), see
<a class="reference external" href="extension_protocol.html">extensions</a>.</li>
<li>add data and parse data from the extension handshake.</li>
<li>send extension messages and standard bittorrent messages.</li>
<li>override or block the handling of standard bittorrent messages.</li>
<li>save and restore state via the <a class="reference external" href="reference-Session.html#session">session</a> state</li>
<li>see all alerts that are posted</li>
</ul>
<div class="section" id="a-word-of-caution">
<h2>a word of caution</h2>
<p>Writing your own <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> is a very easy way to introduce serious bugs such as
dead locks and race conditions. Since a <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> has access to internal
structures it is also quite easy to sabotage libtorrent's operation.</p>
<p>All the callbacks in this interface are called with the main libtorrent thread
mutex locked. And they are always called from the libtorrent network thread. In
case portions of your <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> are called from other threads, typically the main
thread, you cannot use any of the member functions on the internal structures
in libtorrent, since those require the mutex to be locked. Futhermore, you would
also need to have a mutex on your own shared data within the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a>, to make
sure it is not accessed at the same time from the libtorrent thread (through a
callback). See <a class="reference external" href="http://www.boost.org/doc/html/mutex.html">boost thread's mutex</a>. If you need to send out a message from
another thread, it is advised to use an internal queue, and do the actual
sending in <tt class="docutils literal">tick()</tt>.</p>
<p>Since the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> interface gives you easy access to internal structures, it
is not supported as a stable API. Plugins should be considered spcific to a
specific version of libtorrent. Although, in practice the internals mostly
don't change that dramatically.</p>
</div>
</div>
<div class="section" id="plugin-interface">
<h1>plugin-interface</h1>
<p>The <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> interface consists of three base classes that the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> may
implement. These are called <a class="reference external" href="reference-Plugins.html#plugin">plugin</a>, <a class="reference external" href="reference-Plugins.html#torrent_plugin">torrent_plugin</a> and <a class="reference external" href="reference-Plugins.html#peer_plugin">peer_plugin</a>.
They are found in the <tt class="docutils literal">&lt;libtorrent/extensions.hpp&gt;</tt> header.</p>
<p>These plugins are instantiated for each <a class="reference external" href="reference-Session.html#session">session</a>, torrent and possibly each peer,
respectively.</p>
<p>For plugins that only need per torrent state, it is enough to only implement
<tt class="docutils literal">torrent_plugin</tt> and pass a constructor function or function object to
<tt class="docutils literal"><span class="pre">session::add_extension()</span></tt> or <tt class="docutils literal"><span class="pre">torrent_handle::add_extension()</span></tt> (if the
torrent has already been started and you want to hook in the extension at
run-time).</p>
<p>The signature of the function is:</p>
<pre class="literal-block">
boost::shared_ptr&lt;torrent_plugin&gt; (*)(torrent*, void*);
</pre>
<p>The first argument is the internal torrent object, the second argument
is the userdata passed to <tt class="docutils literal"><span class="pre">session::add_torrent()</span></tt> or
<tt class="docutils literal"><span class="pre">torrent_handle::add_extension()</span></tt>.</p>
<p>The function should return a <tt class="docutils literal"><span class="pre">boost::shared_ptr&lt;torrent_plugin&gt;</span></tt> which
may or may not be 0. If it is a null pointer, the extension is simply ignored
for this torrent. If it is a valid pointer (to a class inheriting
<tt class="docutils literal">torrent_plugin</tt>), it will be associated with this torrent and callbacks
will be made on torrent events.</p>
<p>For more elaborate plugins which require <a class="reference external" href="reference-Session.html#session">session</a> wide state, you would
implement <tt class="docutils literal">plugin</tt>, construct an object (in a <tt class="docutils literal"><span class="pre">boost::shared_ptr</span></tt>) and pass
it in to <tt class="docutils literal"><span class="pre">session::add_extension()</span></tt>.</p>
</div>
<div class="section" id="custom-alerts">
<h1>custom alerts</h1>
<p>Since plugins are running within internal libtorrent threads, one convenient
way to communicate with the client is to post custom alerts.</p>
<p>The expected interface of any <a class="reference external" href="reference-Alerts.html#alert">alert</a>, apart from deriving from the <a class="reference external" href="reference-Alerts.html#alert">alert</a>
base class, looks like this:</p>
<pre class="literal-block">
const static int alert_type = <em>&lt;unique alert ID&gt;</em>;
virtual int type() const { return alert_type; }
virtual std::string message() const;
virtual std::auto_ptr&lt;alert&gt; clone() const
{ return std::auto_ptr&lt;alert&gt;(new name(*this)); }
const static int static_category = <em>&lt;bitmask of alert::category_t flags&gt;</em>;
virtual int category() const { return static_category; }
virtual char const* what() const { return <em>&lt;string literal of the name of this alert&gt;</em>; }
</pre>
<p>The <tt class="docutils literal">alert_type</tt> is used for the type-checking in <tt class="docutils literal">alert_cast</tt>. It must
not collide with any other <a class="reference external" href="reference-Alerts.html#alert">alert</a>. The built-in alerts in libtorrent will
not use <a class="reference external" href="reference-Alerts.html#alert">alert</a> type IDs greater than <tt class="docutils literal">user_alert_id</tt>. When defining your
own <a class="reference external" href="reference-Alerts.html#alert">alert</a>, make sure it's greater than this constant.</p>
<p><tt class="docutils literal">type()</tt> is the run-time equivalence of the <tt class="docutils literal">alert_type</tt>.</p>
<p>The <tt class="docutils literal">message()</tt> virtual function is expected to construct a useful
string representation of the <a class="reference external" href="reference-Alerts.html#alert">alert</a> and the event or data it represents.
Something convenient to put in a log file for instance.</p>
<p><tt class="docutils literal">clone()</tt> is used internally to copy alerts. The suggested implementation
of simply allocating a new instance as a copy of <tt class="docutils literal">*this</tt> is all that's
expected.</p>
<p>The static category is required for checking wether or not the category
for a specific <a class="reference external" href="reference-Alerts.html#alert">alert</a> is enabled or not, without instantiating the <a class="reference external" href="reference-Alerts.html#alert">alert</a>.
The <tt class="docutils literal">category</tt> virtual function is the run-time equivalence.</p>
<p>The <tt class="docutils literal">what()</tt> virtual function may simply be a string literal of the class
name of your <a class="reference external" href="reference-Alerts.html#alert">alert</a>.</p>
<p>For more information, see the <a class="reference external" href="reference-Alerts.html">alert section</a>.</p>
<a name="plugin"></a><div class="section" id="plugin">
<h2>plugin</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions.hpp">libtorrent/extensions.hpp</a>&quot;</p>
<p>this is the base class for a <a class="reference external" href="reference-Session.html#session">session</a> <a class="reference external" href="reference-Plugins.html#plugin">plugin</a>. One primary feature
is that it is notified of all torrents that are added to the <a class="reference external" href="reference-Session.html#session">session</a>,
and can add its own torrent_plugins.</p>
<pre class="literal-block">
struct plugin
{
virtual boost::shared_ptr&lt;torrent_plugin&gt; <strong>new_torrent</strong> (torrent*, void*);
virtual void <strong>added</strong> (boost::weak_ptr&lt;aux::session_impl&gt;);
virtual void <strong>on_alert</strong> (alert const*);
virtual void <strong>on_tick</strong> ();
virtual void <strong>save_state</strong> (entry&amp;) const;
virtual void <strong>load_state</strong> (lazy_entry const&amp;);
};
</pre>
<a name="new_torrent()"></a><div class="section" id="new-torrent">
<h3>new_torrent()</h3>
<pre class="literal-block">
virtual boost::shared_ptr&lt;torrent_plugin&gt; <strong>new_torrent</strong> (torrent*, void*);
</pre>
<p>this is called by the <a class="reference external" href="reference-Session.html#session">session</a> every time a new torrent is added.
The <tt class="docutils literal">torrent*</tt> points to the internal torrent object created
for the new torrent. The <tt class="docutils literal">void*</tt> is the userdata pointer as
passed in via <a class="reference external" href="reference-Session.html#add_torrent_params">add_torrent_params</a>.</p>
<p>If the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> returns a <a class="reference external" href="reference-Plugins.html#torrent_plugin">torrent_plugin</a> instance, it will be added
to the new torrent. Otherwise, return an empty shared_ptr to a
<a class="reference external" href="reference-Plugins.html#torrent_plugin">torrent_plugin</a> (the default).</p>
<a name="added()"></a></div>
<div class="section" id="added">
<h3>added()</h3>
<pre class="literal-block">
virtual void <strong>added</strong> (boost::weak_ptr&lt;aux::session_impl&gt;);
</pre>
<p>called when <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> is added to a <a class="reference external" href="reference-Session.html#session">session</a></p>
<a name="on_alert()"></a></div>
<div class="section" id="on-alert">
<h3>on_alert()</h3>
<pre class="literal-block">
virtual void <strong>on_alert</strong> (alert const*);
</pre>
<p>called when an <a class="reference external" href="reference-Alerts.html#alert">alert</a> is posted
alerts that are filtered are not
posted</p>
<a name="on_tick()"></a></div>
<div class="section" id="on-tick">
<h3>on_tick()</h3>
<pre class="literal-block">
virtual void <strong>on_tick</strong> ();
</pre>
<p>called once per second</p>
<a name="save_state()"></a></div>
<div class="section" id="save-state">
<h3>save_state()</h3>
<pre class="literal-block">
virtual void <strong>save_state</strong> (entry&amp;) const;
</pre>
<p>called when saving settings state</p>
<a name="load_state()"></a></div>
<div class="section" id="load-state">
<h3>load_state()</h3>
<pre class="literal-block">
virtual void <strong>load_state</strong> (lazy_entry const&amp;);
</pre>
<p>called when loading settings state</p>
<a name="torrent_plugin"></a></div>
</div>
<div class="section" id="torrent-plugin">
<h2>torrent_plugin</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions.hpp">libtorrent/extensions.hpp</a>&quot;</p>
<p>Torrent plugins are associated with a single torrent and have a number
of functions called at certain events. Many of its functions have the
ability to change or override the default libtorrent behavior.</p>
<pre class="literal-block">
struct torrent_plugin
{
virtual boost::shared_ptr&lt;peer_plugin&gt; <strong>new_connection</strong> (peer_connection*);
virtual void <strong>on_piece_pass</strong> (int /<em>index</em>/);
virtual void <strong>on_piece_failed</strong> (int /<em>index</em>/);
virtual void <strong>tick</strong> ();
virtual bool <strong>on_resume</strong> ();
virtual bool <strong>on_pause</strong> ();
virtual void <strong>on_files_checked</strong> ();
virtual void <strong>on_state</strong> (int /<em>s</em>/);
virtual void <strong>on_add_peer</strong> (<a class="reference external" href="tcp::endpoint">tcp::endpoint</a> const&amp;,
int /<em>src</em>/, int /<em>flags</em>/);
};
</pre>
<a name="new_connection()"></a><div class="section" id="new-connection">
<h3>new_connection()</h3>
<pre class="literal-block">
virtual boost::shared_ptr&lt;peer_plugin&gt; <strong>new_connection</strong> (peer_connection*);
</pre>
<p>This function is called each time a new peer is connected to the torrent. You
may choose to ignore this by just returning a default constructed
<tt class="docutils literal">shared_ptr</tt> (in which case you don't need to override this member
function).</p>
<p>If you need an extension to the peer connection (which most plugins do) you
are supposed to return an instance of your <a class="reference external" href="reference-Plugins.html#peer_plugin">peer_plugin</a> class. Which in
turn will have its hook functions called on event specific to that peer.</p>
<p>The <tt class="docutils literal">peer_connection</tt> will be valid as long as the <tt class="docutils literal">shared_ptr</tt> is being
held by the torrent object. So, it is generally a good idea to not keep a
<tt class="docutils literal">shared_ptr</tt> to your own <a class="reference external" href="reference-Plugins.html#peer_plugin">peer_plugin</a>. If you want to keep references to it,
use <tt class="docutils literal">weak_ptr</tt>.</p>
<p>If this function throws an exception, the connection will be closed.</p>
<a name="on_piece_failed()"></a>
<a name="on_piece_pass()"></a></div>
<div class="section" id="on-piece-failed-on-piece-pass">
<h3>on_piece_failed() on_piece_pass()</h3>
<pre class="literal-block">
virtual void <strong>on_piece_pass</strong> (int /<em>index</em>/);
virtual void <strong>on_piece_failed</strong> (int /<em>index</em>/);
</pre>
<p>These hooks are called when a piece passes the hash check or fails the hash
check, respectively. The <tt class="docutils literal">index</tt> is the piece index that was downloaded.
It is possible to access the list of peers that participated in sending the
piece through the <tt class="docutils literal">torrent</tt> and the <tt class="docutils literal">piece_picker</tt>.</p>
<a name="tick()"></a></div>
<div class="section" id="tick">
<h3>tick()</h3>
<pre class="literal-block">
virtual void <strong>tick</strong> ();
</pre>
<p>This hook is called approximately once per second. It is a way of making it
easy for plugins to do timed events, for sending messages or whatever.</p>
<a name="on_resume()"></a>
<a name="on_pause()"></a></div>
<div class="section" id="on-resume-on-pause">
<h3>on_resume() on_pause()</h3>
<pre class="literal-block">
virtual bool <strong>on_resume</strong> ();
virtual bool <strong>on_pause</strong> ();
</pre>
<p>These hooks are called when the torrent is paused and unpaused respectively.
The return value indicates if the event was handled. A return value of
<tt class="docutils literal">true</tt> indicates that it was handled, and no other <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> after this one
will have this hook function called, and the standard handler will also not be
invoked. So, returning true effectively overrides the standard behavior of
pause or unpause.</p>
<p>Note that if you call <tt class="docutils literal">pause()</tt> or <tt class="docutils literal">resume()</tt> on the torrent from your
handler it will recurse back into your handler, so in order to invoke the
standard handler, you have to keep your own state on whether you want standard
behavior or overridden behavior.</p>
<a name="on_files_checked()"></a></div>
<div class="section" id="on-files-checked">
<h3>on_files_checked()</h3>
<pre class="literal-block">
virtual void <strong>on_files_checked</strong> ();
</pre>
<p>This function is called when the initial files of the torrent have been
checked. If there are no files to check, this function is called immediately.</p>
<p>i.e. This function is always called when the torrent is in a state where it
can start downloading.</p>
<a name="on_state()"></a></div>
<div class="section" id="on-state">
<h3>on_state()</h3>
<pre class="literal-block">
virtual void <strong>on_state</strong> (int /<em>s</em>/);
</pre>
<p>called when the torrent changes state
the state is one of <a class="reference external" href="reference-Core.html#state_t">torrent_status::state_t</a>
enum members</p>
<a name="on_add_peer()"></a></div>
<div class="section" id="on-add-peer">
<h3>on_add_peer()</h3>
<pre class="literal-block">
virtual void <strong>on_add_peer</strong> (<a class="reference external" href="tcp::endpoint">tcp::endpoint</a> const&amp;,
int /<em>src</em>/, int /<em>flags</em>/);
</pre>
<p>called every time a new peer is added to the peer list.
This is before the peer is connected to. For <tt class="docutils literal">flags</tt>, see
torrent_plugin::flags_t. The <tt class="docutils literal">source</tt> argument refers to
the source where we learned about this peer from. It's a
bitmask, because many sources may have told us about the same
peer. For peer source flags, see <a class="reference external" href="reference-Core.html#peer_source_flags">peer_info::peer_source_flags</a>.</p>
<a name="peer_plugin"></a></div>
</div>
<div class="section" id="peer-plugin">
<h2>peer_plugin</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions.hpp">libtorrent/extensions.hpp</a>&quot;</p>
<p>peer plugins are associated with a specific peer. A peer could be
both a regular bittorrent peer (<tt class="docutils literal">bt_peer_connection</tt>) or one of the
web seed connections (<tt class="docutils literal">web_peer_connection</tt> or <tt class="docutils literal">http_seed_connection</tt>).
In order to only attach to certain peers, make your
torrent_plugin::new_connection only return a <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> for certain peer
connection types</p>
<pre class="literal-block">
struct peer_plugin
{
virtual char const* <strong>type</strong> () const;
virtual void <strong>add_handshake</strong> (entry&amp;);
virtual void <strong>on_disconnect</strong> (error_code const&amp; ec);
virtual void <strong>on_connected</strong> ();
virtual bool <strong>on_handshake</strong> (char const* /<em>reserved_bits</em>/);
virtual bool <strong>on_extension_handshake</strong> (lazy_entry const&amp;);
virtual bool <strong>on_have</strong> (int /<em>index</em>/);
virtual bool <strong>on_bitfield</strong> (bitfield const&amp; /<em>bitfield</em>/);
virtual bool <strong>on_have_all</strong> ();
virtual bool <strong>on_reject</strong> (peer_request const&amp;);
virtual bool <strong>on_request</strong> (peer_request const&amp;);
virtual bool <strong>on_unchoke</strong> ();
virtual bool <strong>on_interested</strong> ();
virtual bool <strong>on_allowed_fast</strong> (int /<em>index</em>/);
virtual bool <strong>on_have_none</strong> ();
virtual bool <strong>on_choke</strong> ();
virtual bool <strong>on_not_interested</strong> ();
virtual bool <strong>on_piece</strong> (peer_request const&amp; /<em>piece</em>/
, disk_buffer_holder&amp; /<em>data</em>/);
virtual bool <strong>on_suggest</strong> (int /<em>index</em>/);
virtual bool <strong>on_cancel</strong> (peer_request const&amp;);
virtual bool <strong>on_dont_have</strong> (int /<em>index</em>/);
virtual bool <strong>can_disconnect</strong> (error_code const&amp; ec);
virtual bool <strong>on_extended</strong> (int /<em>length</em>/, int /<em>msg</em>/,
buffer::const_interval /<em>body</em>/);
virtual bool <strong>on_unknown_message</strong> (int /<em>length</em>/, int /<em>msg</em>/,
buffer::const_interval /<em>body</em>/);
virtual void <strong>on_piece_pass</strong> (int /<em>index</em>/);
virtual void <strong>on_piece_failed</strong> (int /<em>index</em>/);
virtual void <strong>tick</strong> ();
virtual bool <strong>write_request</strong> (peer_request const&amp;);
};
</pre>
<a name="type()"></a><div class="section" id="type">
<h3>type()</h3>
<pre class="literal-block">
virtual char const* <strong>type</strong> () const;
</pre>
<p>This function is expected to return the name of
the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a>.</p>
<a name="add_handshake()"></a></div>
<div class="section" id="add-handshake">
<h3>add_handshake()</h3>
<pre class="literal-block">
virtual void <strong>add_handshake</strong> (entry&amp;);
</pre>
<p>can add entries to the extension handshake
this is not called for web seeds</p>
<a name="on_disconnect()"></a></div>
<div class="section" id="on-disconnect">
<h3>on_disconnect()</h3>
<pre class="literal-block">
virtual void <strong>on_disconnect</strong> (error_code const&amp; ec);
</pre>
<p>called when the peer is being disconnected.</p>
<a name="on_connected()"></a></div>
<div class="section" id="on-connected">
<h3>on_connected()</h3>
<pre class="literal-block">
virtual void <strong>on_connected</strong> ();
</pre>
<p>called when the peer is successfully connected. Note that
incoming connections will have been connected by the time
the peer <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> is attached to it, and won't have this hook
called.</p>
<a name="on_handshake()"></a></div>
<div class="section" id="on-handshake">
<h3>on_handshake()</h3>
<pre class="literal-block">
virtual bool <strong>on_handshake</strong> (char const* /<em>reserved_bits</em>/);
</pre>
<p>this is called when the initial BT handshake is received. Returning false
means that the other end doesn't support this extension and will remove
it from the list of plugins.
this is not called for web seeds</p>
<a name="on_extension_handshake()"></a></div>
<div class="section" id="on-extension-handshake">
<h3>on_extension_handshake()</h3>
<pre class="literal-block">
virtual bool <strong>on_extension_handshake</strong> (lazy_entry const&amp;);
</pre>
<p>called when the extension handshake from the other end is received
if this returns false, it means that this extension isn't
supported by this peer. It will result in this <a class="reference external" href="reference-Plugins.html#peer_plugin">peer_plugin</a>
being removed from the peer_connection and destructed.
this is not called for web seeds</p>
<a name="on_bitfield()"></a>
<a name="on_have_none()"></a>
<a name="on_suggest()"></a>
<a name="on_unchoke()"></a>
<a name="on_cancel()"></a>
<a name="on_have()"></a>
<a name="on_choke()"></a>
<a name="on_piece()"></a>
<a name="on_request()"></a>
<a name="on_reject()"></a>
<a name="on_not_interested()"></a>
<a name="on_interested()"></a>
<a name="on_allowed_fast()"></a>
<a name="on_have_all()"></a>
<a name="on_dont_have()"></a></div>
<div class="section" id="on-bitfield-on-have-none-on-suggest-on-unchoke-on-cancel-on-have-on-choke-on-piece-on-request-on-reject-on-not-interested-on-interested-on-allowed-fast-on-have-all-on-dont-have">
<h3>on_bitfield() on_have_none() on_suggest() on_unchoke() on_cancel() on_have() on_choke() on_piece() on_request() on_reject() on_not_interested() on_interested() on_allowed_fast() on_have_all() on_dont_have()</h3>
<pre class="literal-block">
virtual bool <strong>on_have</strong> (int /<em>index</em>/);
virtual bool <strong>on_bitfield</strong> (bitfield const&amp; /<em>bitfield</em>/);
virtual bool <strong>on_have_all</strong> ();
virtual bool <strong>on_reject</strong> (peer_request const&amp;);
virtual bool <strong>on_request</strong> (peer_request const&amp;);
virtual bool <strong>on_unchoke</strong> ();
virtual bool <strong>on_interested</strong> ();
virtual bool <strong>on_allowed_fast</strong> (int /<em>index</em>/);
virtual bool <strong>on_have_none</strong> ();
virtual bool <strong>on_choke</strong> ();
virtual bool <strong>on_not_interested</strong> ();
virtual bool <strong>on_piece</strong> (peer_request const&amp; /<em>piece</em>/
, disk_buffer_holder&amp; /<em>data</em>/);
virtual bool <strong>on_suggest</strong> (int /<em>index</em>/);
virtual bool <strong>on_cancel</strong> (peer_request const&amp;);
virtual bool <strong>on_dont_have</strong> (int /<em>index</em>/);
</pre>
<p>returning true from any of the message handlers
indicates that the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> has handeled the message.
it will break the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> chain traversing and not let
anyone else handle the message, including the default
handler.</p>
<a name="can_disconnect()"></a></div>
<div class="section" id="can-disconnect">
<h3>can_disconnect()</h3>
<pre class="literal-block">
virtual bool <strong>can_disconnect</strong> (error_code const&amp; ec);
</pre>
<p>called when libtorrent think this peer should be disconnected.
if the <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> returns false, the peer will not be disconnected.</p>
<a name="on_extended()"></a></div>
<div class="section" id="on-extended">
<h3>on_extended()</h3>
<pre class="literal-block">
virtual bool <strong>on_extended</strong> (int /<em>length</em>/, int /<em>msg</em>/,
buffer::const_interval /<em>body</em>/);
</pre>
<p>called when an extended message is received. If returning true,
the message is not processed by any other <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> and if false
is returned the next <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> in the chain will receive it to
be able to handle it
this is not called for web seeds</p>
<a name="on_unknown_message()"></a></div>
<div class="section" id="on-unknown-message">
<h3>on_unknown_message()</h3>
<pre class="literal-block">
virtual bool <strong>on_unknown_message</strong> (int /<em>length</em>/, int /<em>msg</em>/,
buffer::const_interval /<em>body</em>/);
</pre>
<p>this is not called for web seeds</p>
<a name="on_piece_failed()"></a>
<a name="on_piece_pass()"></a></div>
<div class="section" id="id53">
<h3>on_piece_failed() on_piece_pass()</h3>
<pre class="literal-block">
virtual void <strong>on_piece_pass</strong> (int /<em>index</em>/);
virtual void <strong>on_piece_failed</strong> (int /<em>index</em>/);
</pre>
<p>called when a piece that this peer participated in either
fails or passes the hash_check</p>
<a name="tick()"></a></div>
<div class="section" id="id54">
<h3>tick()</h3>
<pre class="literal-block">
virtual void <strong>tick</strong> ();
</pre>
<p>called aproximately once every second</p>
<a name="write_request()"></a></div>
<div class="section" id="write-request">
<h3>write_request()</h3>
<pre class="literal-block">
virtual bool <strong>write_request</strong> (peer_request const&amp;);
</pre>
<p>called each time a request message is to be sent. If true
is returned, the original request message won't be sent and
no other <a class="reference external" href="reference-Plugins.html#plugin">plugin</a> will have this function called.</p>
<a name="create_lt_trackers_plugin()"></a></div>
<div class="section" id="create-lt-trackers-plugin">
<h3>create_lt_trackers_plugin()</h3>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions/lt_trackers.hpp">libtorrent/extensions/lt_trackers.hpp</a>&quot;</p>
<pre class="literal-block">
boost::shared_ptr&lt;torrent_plugin&gt; <strong>create_lt_trackers_plugin</strong> (torrent*, void*);
</pre>
<p>constructor function for the trackers exchange extension. This can
either be passed in the add_torrent_params::extensions field, or
via <a class="reference external" href="reference-Core.html#add_extension()">torrent_handle::add_extension()</a>.</p>
<a name="create_smart_ban_plugin()"></a></div>
<div class="section" id="create-smart-ban-plugin">
<h3>create_smart_ban_plugin()</h3>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions/smart_ban.hpp">libtorrent/extensions/smart_ban.hpp</a>&quot;</p>
<pre class="literal-block">
boost::shared_ptr&lt;torrent_plugin&gt; <strong>create_smart_ban_plugin</strong> (torrent*, void*);
</pre>
<p>constructor function for the smart ban extension. The extension keeps
track of the data peers have sent us for failing pieces and once the
piece completes and passes the hash check bans the peers that turned
out to have sent corrupt data.
This function can either be passed in the add_torrent_params::extensions
field, or via <a class="reference external" href="reference-Core.html#add_extension()">torrent_handle::add_extension()</a>.</p>
<a name="create_ut_metadata_plugin()"></a></div>
<div class="section" id="create-ut-metadata-plugin">
<h3>create_ut_metadata_plugin()</h3>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions/ut_metadata.hpp">libtorrent/extensions/ut_metadata.hpp</a>&quot;</p>
<pre class="literal-block">
boost::shared_ptr&lt;torrent_plugin&gt; <strong>create_ut_metadata_plugin</strong> (torrent*, void*);
</pre>
<p>constructor function for the ut_metadata extension. The ut_metadata
extension allows peers to request the .torrent file (or more
specifically the 'info'-dictionary of the .torrent file) from each
other. This is the main building block in making magnet links work.
This extension is enabled by default unless explicitly disabled in
the <a class="reference external" href="reference-Session.html#session">session</a> constructor.</p>
<p>This can either be passed in the add_torrent_params::extensions field, or
via <a class="reference external" href="reference-Core.html#add_extension()">torrent_handle::add_extension()</a>.</p>
<a name="create_ut_pex_plugin()"></a></div>
<div class="section" id="create-ut-pex-plugin">
<h3>create_ut_pex_plugin()</h3>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/extensions/ut_pex.hpp">libtorrent/extensions/ut_pex.hpp</a>&quot;</p>
<pre class="literal-block">
boost::shared_ptr&lt;torrent_plugin&gt; <strong>create_ut_pex_plugin</strong> (torrent*, void*);
</pre>
<p>constructor function for the ut_pex extension. The ut_pex
extension allows peers to gossip about their connections, allowing
the swarm stay well connected and peers aware of more peers in the
swarm. This extension is enabled by default unless explicitly disabled in
the <a class="reference external" href="reference-Session.html#session">session</a> constructor.</p>
<p>This can either be passed in the add_torrent_params::extensions field, or
via <a class="reference external" href="reference-Core.html#add_extension()">torrent_handle::add_extension()</a>.</p>
</div>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

309
docs/reference-RSS.html Normal file
View File

@ -0,0 +1,309 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>RSS</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="rss">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">RSS</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#feed-item" id="id25">feed_item</a></li>
<li><a class="reference internal" href="#feed-settings" id="id26">feed_settings</a></li>
<li><a class="reference internal" href="#feed-status" id="id27">feed_status</a></li>
<li><a class="reference internal" href="#feed-handle" id="id28">feed_handle</a></li>
</ul>
</div>
<a name="feed_item"></a><div class="section" id="feed-item">
<h1>feed_item</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/rss.hpp">libtorrent/rss.hpp</a>&quot;</p>
<p>represents one item from an RSS feed. Specifically
a feed of torrents.</p>
<pre class="literal-block">
struct feed_item
{
<strong>feed_item</strong> ();
<strong>~feed_item</strong> ();
std::string url;
std::string uuid;
std::string title;
std::string description;
std::string comment;
std::string category;
size_type size;
torrent_handle handle;
sha1_hash info_hash;
};
</pre>
<a name="url"></a>
<a name="uuid"></a>
<a name="title"></a>
<a name="description"></a>
<a name="comment"></a>
<a name="category"></a><dl class="docutils">
<dt>url uuid title description comment category</dt>
<dd>these are self explanatory and may be empty if the feed does not specify
those fields.</dd>
</dl>
<a name="size"></a><dl class="docutils">
<dt>size</dt>
<dd>the total size of the content the torrent refers to, or -1
if no size was specified by the feed.</dd>
</dl>
<a name="handle"></a><dl class="docutils">
<dt>handle</dt>
<dd>the handle to the torrent, if the <a class="reference external" href="reference-Session.html#session">session</a> is already downloading
this torrent.</dd>
</dl>
<a name="info_hash"></a><dl class="docutils">
<dt>info_hash</dt>
<dd>the info-hash of the torrent, or cleared (i.e. all zeroes) if
the feed does not specify the info-hash.</dd>
</dl>
<a name="feed_settings"></a></div>
<div class="section" id="feed-settings">
<h1>feed_settings</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/rss.hpp">libtorrent/rss.hpp</a>&quot;</p>
<p>the <a class="reference external" href="reference-RSS.html#feed_settings">feed_settings</a> object is all the information
and configuration for a specific feed. All of
these settings can be changed by the user
after adding the feed</p>
<pre class="literal-block">
struct feed_settings
{
<strong>feed_settings</strong> ();
std::string url;
bool auto_download;
bool auto_map_handles;
int default_ttl;
add_torrent_params add_args;
};
</pre>
<a name="auto_download"></a><dl class="docutils">
<dt>auto_download</dt>
<dd>By default <tt class="docutils literal">auto_download</tt> is true, which means all torrents in
the feed will be downloaded. Set this to false in order to manually
add torrents to the <a class="reference external" href="reference-Session.html#session">session</a>. You may react to the <a class="reference external" href="reference-Alerts.html#rss_alert">rss_alert</a> when
a feed has been updated to poll it for the new items in the feed
when adding torrents manually. When torrents are added automatically,
an <a class="reference external" href="reference-Alerts.html#add_torrent_alert">add_torrent_alert</a> is posted which includes the torrent handle
as well as the error code if it failed to be added. You may also call
<tt class="docutils literal"><span class="pre">session::get_torrents()</span></tt> to get the handles to the new torrents.</dd>
</dl>
<a name="auto_map_handles"></a><dl class="docutils">
<dt>auto_map_handles</dt>
<dd><tt class="docutils literal">auto_map_handles</tt> defaults to true and determines whether or
not to set the <tt class="docutils literal">handle</tt> field in the <a class="reference external" href="reference-RSS.html#feed_item">feed_item</a>, returned
as the feed status. If auto-download is enabled, this setting
is ignored. If auto-download is not set, setting this to false
will save one pass through all the feed items trying to find
corresponding torrents in the <a class="reference external" href="reference-Session.html#session">session</a>.</dd>
</dl>
<a name="default_ttl"></a><dl class="docutils">
<dt>default_ttl</dt>
<dd>The <tt class="docutils literal">default_ttl</tt> is the default interval for refreshing a feed.
This may be overridden by the feed itself (by specifying the <tt class="docutils literal">&lt;ttl&gt;</tt>
tag) and defaults to 30 minutes. The field specifies the number of
minutes between refreshes.</dd>
</dl>
<a name="add_args"></a><dl class="docutils">
<dt>add_args</dt>
<dd>If torrents are added automatically, you may want to set the
<tt class="docutils literal">add_args</tt> to appropriate values for download directory etc.
This object is used as a template for adding torrents from feeds,
but some torrent specific fields will be overridden by the
individual torrent being added. For more information on the
<a class="reference external" href="reference-Session.html#add_torrent_params">add_torrent_params</a>, see <a class="reference external" href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <a class="reference external" href="reference-Session.html#add_torrent()">add_torrent()</a>.</dd>
</dl>
<a name="feed_status"></a></div>
<div class="section" id="feed-status">
<h1>feed_status</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/rss.hpp">libtorrent/rss.hpp</a>&quot;</p>
<p>holds information about the status of an RSS feed. Retrieved by
calling <a class="reference external" href="reference-RSS.html#get_feed_status()">get_feed_status()</a> on <a class="reference external" href="reference-RSS.html#feed_handle">feed_handle</a>.</p>
<pre class="literal-block">
struct feed_status
{
<strong>feed_status</strong> ();
std::string url;
std::string title;
std::string description;
time_t last_update;
int next_update;
bool updating;
std::vector&lt;feed_item&gt; items;
error_code error;
int ttl;
};
</pre>
<a name="url"></a><dl class="docutils">
<dt>url</dt>
<dd>the URL of the feed.</dd>
</dl>
<a name="title"></a><dl class="docutils">
<dt>title</dt>
<dd>the name of the feed (as specified by the feed itself). This
may be empty if we have not recevied a response from the RSS server yet,
or if the feed does not specify a title.</dd>
</dl>
<a name="description"></a><dl class="docutils">
<dt>description</dt>
<dd>the feed description (as specified by the feed itself).
This may be empty if we have not received a response from the RSS server
yet, or if the feed does not specify a description.</dd>
</dl>
<a name="last_update"></a><dl class="docutils">
<dt>last_update</dt>
<dd>the posix time of the last successful response from the feed.</dd>
</dl>
<a name="next_update"></a><dl class="docutils">
<dt>next_update</dt>
<dd>the number of seconds, from now, when the feed will be
updated again.</dd>
</dl>
<a name="updating"></a><dl class="docutils">
<dt>updating</dt>
<dd>true if the feed is currently being updated (i.e. waiting for
DNS resolution, connecting to the server or waiting for the response to the
HTTP request, or receiving the response).</dd>
</dl>
<a name="items"></a><dl class="docutils">
<dt>items</dt>
<dd>a vector of all items that we have received from the feed. See
<a class="reference external" href="reference-RSS.html#feed_item">feed_item</a> for more information.</dd>
</dl>
<a name="error"></a><dl class="docutils">
<dt>error</dt>
<dd>set to the appropriate error code if the feed encountered an
error. See error_code for more info.</dd>
</dl>
<a name="ttl"></a><dl class="docutils">
<dt>ttl</dt>
<dd>the current refresh time (in minutes). It's either the configured
default ttl, or the ttl specified by the feed.</dd>
</dl>
<a name="feed_handle"></a></div>
<div class="section" id="feed-handle">
<h1>feed_handle</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/rss.hpp">libtorrent/rss.hpp</a>&quot;</p>
<p>The <tt class="docutils literal">feed_handle</tt> refers to a specific RSS feed that is watched by the <a class="reference external" href="reference-Session.html#session">session</a>.</p>
<pre class="literal-block">
struct feed_handle
{
<strong>feed_handle</strong> ();
void <strong>update_feed</strong> ();
feed_status <strong>get_feed_status</strong> () const;
void <strong>set_settings</strong> (feed_settings const&amp; s);
feed_settings <strong>settings</strong> () const;
};
</pre>
<a name="update_feed()"></a><div class="section" id="update-feed">
<h2>update_feed()</h2>
<pre class="literal-block">
void <strong>update_feed</strong> ();
</pre>
<p>Forces an update/refresh of the feed. Regular updates of the feed is managed
by libtorrent, be careful to not call this too frequently since it may
overload the RSS server.</p>
<a name="get_feed_status()"></a></div>
<div class="section" id="get-feed-status">
<h2>get_feed_status()</h2>
<pre class="literal-block">
feed_status <strong>get_feed_status</strong> () const;
</pre>
<p>Queries the RSS feed for information, including all the items in the feed.
see <a class="reference external" href="reference-RSS.html#feed_status">feed_status</a>.</p>
<a name="settings()"></a>
<a name="set_settings()"></a></div>
<div class="section" id="settings-set-settings">
<h2>settings() set_settings()</h2>
<pre class="literal-block">
void <strong>set_settings</strong> (feed_settings const&amp; s);
feed_settings <strong>settings</strong> () const;
</pre>
<p>Sets and gets settings for this feed. For more information on the
available settings, see <a class="reference external" href="reference-Session.html#add_feed()">add_feed()</a>.</p>
<a name="add_feed_item()"></a></div>
<div class="section" id="add-feed-item">
<h2>add_feed_item()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/rss.hpp">libtorrent/rss.hpp</a>&quot;</p>
<pre class="literal-block">
torrent_handle <strong>add_feed_item</strong> (session&amp; s, feed_item const&amp; fi
, add_torrent_params const&amp; p);
torrent_handle <strong>add_feed_item</strong> (session&amp; s, feed_item const&amp; fi
, add_torrent_params const&amp; p, error_code&amp; ec);
</pre>
<p>given a <a class="reference external" href="reference-RSS.html#feed_item">feed_item</a> <tt class="docutils literal">f</tt>, add the torrent it refers to to <a class="reference external" href="reference-Session.html#session">session</a> <tt class="docutils literal">s</tt>.</p>
<a name="new_feed()"></a></div>
<div class="section" id="new-feed">
<h2>new_feed()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/rss.hpp">libtorrent/rss.hpp</a>&quot;</p>
<pre class="literal-block">
boost::shared_ptr&lt;feed&gt; <strong>new_feed</strong> (aux::session_impl&amp; ses, feed_settings const&amp; sett);
</pre>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

View File

@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Session</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />

1913
docs/reference-Settings.html Normal file

File diff suppressed because it is too large Load Diff

612
docs/reference-Storage.html Normal file
View File

@ -0,0 +1,612 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Storage</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="storage">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Storage</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#file-entry" id="id25">file_entry</a></li>
<li><a class="reference internal" href="#file-slice" id="id26">file_slice</a></li>
<li><a class="reference internal" href="#file-storage" id="id27">file_storage</a></li>
</ul>
</div>
<a name="file_entry"></a><div class="section" id="file-entry">
<h1>file_entry</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/file_storage.hpp">libtorrent/file_storage.hpp</a>&quot;</p>
<p>information about a file in a <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a></p>
<pre class="literal-block">
struct file_entry
{
std::string path;
std::string symlink_path;
size_type offset;
size_type size;
size_type file_base;
std::time_t mtime;
sha1_hash filehash;
bool pad_file:1;
bool hidden_attribute:1;
bool executable_attribute:1;
bool symlink_attribute:1;
};
</pre>
<a name="path"></a><dl class="docutils">
<dt>path</dt>
<dd>the full path of this file. The paths are unicode strings
encoded in UTF-8.</dd>
</dl>
<a name="symlink_path"></a><dl class="docutils">
<dt>symlink_path</dt>
<dd>the path which this is a symlink to, or empty if this is
not a symlink. This field is only used if the <tt class="docutils literal">symlink_attribute</tt> is set.</dd>
</dl>
<a name="offset"></a><dl class="docutils">
<dt>offset</dt>
<dd>the offset of this file inside the torrent</dd>
</dl>
<a name="size"></a><dl class="docutils">
<dt>size</dt>
<dd>the size of the file (in bytes) and <tt class="docutils literal">offset</tt> is the byte offset
of the file within the torrent. i.e. the sum of all the sizes of the files
before it in the list.</dd>
</dl>
<a name="file_base"></a><dl class="docutils">
<dt>file_base</dt>
<dd>the offset in the file where the storage should start. The normal
case is to have this set to 0, so that the storage starts saving data at the start
if the file. In cases where multiple files are mapped into the same file though,
the <tt class="docutils literal">file_base</tt> should be set to an offset so that the different regions do
not overlap. This is used when mapping &quot;unselected&quot; files into a so-called part
file.</dd>
</dl>
<a name="mtime"></a><dl class="docutils">
<dt>mtime</dt>
<dd>the modification time of this file specified in posix time.</dd>
</dl>
<a name="filehash"></a><dl class="docutils">
<dt>filehash</dt>
<dd>a sha-1 hash of the content of the file, or zeroes, if no
file hash was present in the torrent file. It can be used to potentially
find alternative sources for the file.</dd>
</dl>
<a name="pad_file"></a><dl class="docutils">
<dt>pad_file</dt>
<dd>set to true for files that are not part of the data of the torrent.
They are just there to make sure the next file is aligned to a particular byte offset
or piece boundry. These files should typically be hidden from an end user. They are
not written to disk.</dd>
</dl>
<a name="hidden_attribute"></a><dl class="docutils">
<dt>hidden_attribute</dt>
<dd>true if the file was marked as hidden (on windows).</dd>
</dl>
<a name="executable_attribute"></a><dl class="docutils">
<dt>executable_attribute</dt>
<dd>true if the file was marked as executable (posix)</dd>
</dl>
<a name="symlink_attribute"></a><dl class="docutils">
<dt>symlink_attribute</dt>
<dd>true if the file was a symlink. If this is the case
the <tt class="docutils literal">symlink_index</tt> refers to a string which specifies the original location
where the data for this file was found.</dd>
</dl>
<a name="file_slice"></a></div>
<div class="section" id="file-slice">
<h1>file_slice</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/file_storage.hpp">libtorrent/file_storage.hpp</a>&quot;</p>
<p>represents a window of a file in a torrent.</p>
<p>The <tt class="docutils literal">file_index</tt> refers to the index of the file (in the <a class="reference external" href="reference-Core.html#torrent_info">torrent_info</a>).
To get the path and filename, use <tt class="docutils literal">file_at()</tt> and give the <tt class="docutils literal">file_index</tt>
as argument. The <tt class="docutils literal">offset</tt> is the byte offset in the file where the range
starts, and <tt class="docutils literal">size</tt> is the number of bytes this range is. The size + offset
will never be greater than the file size.</p>
<pre class="literal-block">
struct file_slice
{
int file_index;
size_type offset;
size_type size;
};
</pre>
<a name="file_index"></a><dl class="docutils">
<dt>file_index</dt>
<dd>the index of the file</dd>
</dl>
<a name="offset"></a><dl class="docutils">
<dt>offset</dt>
<dd>the offset from the start of the file, in bytes</dd>
</dl>
<a name="size"></a><dl class="docutils">
<dt>size</dt>
<dd>the size of the window, in bytes</dd>
</dl>
<a name="file_storage"></a></div>
<div class="section" id="file-storage">
<h1>file_storage</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/file_storage.hpp">libtorrent/file_storage.hpp</a>&quot;</p>
<p>The <tt class="docutils literal">file_storage</tt> class represents a file list and the piece
size. Everything necessary to interpret a regular bittorrent storage
file structure.</p>
<pre class="literal-block">
class file_storage
{
bool <strong>is_valid</strong> () const;
void <strong>reserve</strong> (int num_files);
void <strong>add_file</strong> (std::string const&amp; p, size_type size, int flags = 0
, std::time_t mtime = 0, std::string const&amp; s_p = &quot;&quot;);
void <strong>add_file</strong> (file_entry const&amp; e, char const* filehash = 0);
void <strong>rename_file</strong> (int index, std::string const&amp; new_filename);
void <strong>rename_file_borrow</strong> (int index, char const* new_filename, int len);
std::vector&lt;file_slice&gt; <strong>map_block</strong> (int piece, size_type offset
, int size) const;
peer_request <strong>map_file</strong> (int file, size_type offset, int size) const;
int <strong>num_files</strong> () const;
file_entry <strong>at</strong> (int index) const;
size_type <strong>total_size</strong> () const;
void <strong>set_num_pieces</strong> (int n);
int <strong>num_pieces</strong> () const;
void <strong>set_piece_length</strong> (int l);
int <strong>piece_length</strong> () const;
int <strong>piece_size</strong> (int index) const;
void <strong>set_name</strong> (std::string const&amp; n);
const std::string&amp; <strong>name</strong> () const;
void <strong>swap</strong> (file_storage&amp; ti);
void <strong>optimize</strong> (int pad_file_limit = -1, int alignment = 0x10000);
size_type <strong>file_size</strong> (int index) const;
sha1_hash <strong>hash</strong> (int index) const;
std::string <strong>file_name</strong> (int index) const;
size_type <strong>file_offset</strong> (int index) const;
time_t <strong>mtime</strong> (int index) const;
bool <strong>pad_file_at</strong> (int index) const;
std::string const&amp; <strong>symlink</strong> (int index) const;
std::string <strong>file_path</strong> (int index, std::string const&amp; save_path = &quot;&quot;) const;
int <strong>file_flags</strong> (int index) const;
void <strong>set_file_base</strong> (int index, size_type off);
size_type <strong>file_base</strong> (int index) const;
int <strong>file_index_at_offset</strong> (size_type offset) const;
char const* <strong>file_name_ptr</strong> (int index) const;
int <strong>file_name_len</strong> (int index) const;
enum flags_t
{
pad_file,
attribute_hidden,
attribute_executable,
attribute_symlink,
};
enum file_flags_t
{
flag_pad_file,
flag_hidden,
flag_executable,
flag_symlink,
};
};
</pre>
<a name="is_valid()"></a><div class="section" id="is-valid">
<h2>is_valid()</h2>
<pre class="literal-block">
bool <strong>is_valid</strong> () const;
</pre>
<p>returns true if the piece length has been initialized
on the <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a>. This is typically taken as a proxy
of whether the <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a> as a whole is initialized or
not.</p>
<a name="reserve()"></a></div>
<div class="section" id="reserve">
<h2>reserve()</h2>
<pre class="literal-block">
void <strong>reserve</strong> (int num_files);
</pre>
<p>allocates space for <tt class="docutils literal">num_files</tt> in the internal file list. This can
be used to avoid reallocating the internal file list when the number
of files to be added is known up-front.</p>
<a name="add_file()"></a></div>
<div class="section" id="add-file">
<h2>add_file()</h2>
<pre class="literal-block">
void <strong>add_file</strong> (std::string const&amp; p, size_type size, int flags = 0
, std::time_t mtime = 0, std::string const&amp; s_p = &quot;&quot;);
void <strong>add_file</strong> (file_entry const&amp; e, char const* filehash = 0);
</pre>
<p>Adds a file to the file storage. The <tt class="docutils literal">flags</tt> argument sets attributes on the file.
The file attributes is an extension and may not work in all bittorrent clients.</p>
<p>For possible file attributes, see <a class="reference external" href="reference-Storage.html#flags_t">file_storage::flags_t</a>.</p>
<p>If more files than one are added, certain restrictions to their paths apply.
In a multi-file file storage (torrent), all files must share the same root directory.</p>
<p>That is, the first path element of all files must be the same.
This shared path element is also set to the name of the torrent. It
can be changed by calling <tt class="docutils literal">set_name</tt>.</p>
<p>The built in functions to traverse a directory to add files will
make sure this requirement is fulfilled.</p>
<a name="rename_file()"></a></div>
<div class="section" id="rename-file">
<h2>rename_file()</h2>
<pre class="literal-block">
void <strong>rename_file</strong> (int index, std::string const&amp; new_filename);
</pre>
<p>renames the file at <tt class="docutils literal">index</tt> to <tt class="docutils literal">new_filename</tt>. Keep in mind
that filenames are expected to be UTF-8 encoded.</p>
<a name="rename_file_borrow()"></a></div>
<div class="section" id="rename-file-borrow">
<h2>rename_file_borrow()</h2>
<pre class="literal-block">
void <strong>rename_file_borrow</strong> (int index, char const* new_filename, int len);
</pre>
<p>this is a low-level function that sets the name of a file
by making it reference a buffer that is not owned by the <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a>.
it's an optimization used when loading .torrent files, to not
duplicate names in memory.</p>
<a name="map_block()"></a></div>
<div class="section" id="map-block">
<h2>map_block()</h2>
<pre class="literal-block">
std::vector&lt;file_slice&gt; <strong>map_block</strong> (int piece, size_type offset
, int size) const;
</pre>
<p>returns a list of <a class="reference external" href="reference-Storage.html#file_slice">file_slice</a> objects representing the portions of
files the specified piece index, byte offset and size range overlaps.
this is the inverse mapping of <a class="reference external" href="reference-Core.html#map_file()">map_file()</a>.</p>
<a name="map_file()"></a></div>
<div class="section" id="map-file">
<h2>map_file()</h2>
<pre class="literal-block">
peer_request <strong>map_file</strong> (int file, size_type offset, int size) const;
</pre>
<p>returns a <a class="reference external" href="reference-Core.html#peer_request">peer_request</a> representing the piece index, byte offset
and size the specified file range overlaps. This is the inverse
mapping ove <a class="reference external" href="reference-Core.html#map_block()">map_block()</a>.</p>
<a name="num_files()"></a></div>
<div class="section" id="num-files">
<h2>num_files()</h2>
<pre class="literal-block">
int <strong>num_files</strong> () const;
</pre>
<p>returns the number of files in the <a class="reference external" href="reference-Storage.html#file_storage">file_storage</a></p>
<a name="at()"></a></div>
<div class="section" id="at">
<h2>at()</h2>
<pre class="literal-block">
file_entry <strong>at</strong> (int index) const;
</pre>
<p>returns a <a class="reference external" href="reference-Storage.html#file_entry">file_entry</a> with information about the file
at <tt class="docutils literal">index</tt>. Index must be in the range [0, <tt class="docutils literal">num_files()</tt> ).</p>
<a name="total_size()"></a></div>
<div class="section" id="total-size">
<h2>total_size()</h2>
<pre class="literal-block">
size_type <strong>total_size</strong> () const;
</pre>
<p>returns the total number of bytes all the files in this torrent spans</p>
<a name="num_pieces()"></a>
<a name="set_num_pieces()"></a></div>
<div class="section" id="num-pieces-set-num-pieces">
<h2>num_pieces() set_num_pieces()</h2>
<pre class="literal-block">
void <strong>set_num_pieces</strong> (int n);
int <strong>num_pieces</strong> () const;
</pre>
<p>set and get the number of pieces in the torrent</p>
<a name="piece_length()"></a>
<a name="set_piece_length()"></a></div>
<div class="section" id="piece-length-set-piece-length">
<h2>piece_length() set_piece_length()</h2>
<pre class="literal-block">
void <strong>set_piece_length</strong> (int l);
int <strong>piece_length</strong> () const;
</pre>
<p>set and get the size of each piece in this torrent. This size is typically an even power
of 2. It doesn't have to be though. It should be divisible by 16kiB however.</p>
<a name="piece_size()"></a></div>
<div class="section" id="piece-size">
<h2>piece_size()</h2>
<pre class="literal-block">
int <strong>piece_size</strong> (int index) const;
</pre>
<p>returns the piece size of <tt class="docutils literal">index</tt>. This will be the same as <a class="reference external" href="reference-Core.html#piece_length()">piece_length()</a>, except
for the last piece, which may be shorter.</p>
<a name="set_name()"></a>
<a name="name()"></a></div>
<div class="section" id="set-name-name">
<h2>set_name() name()</h2>
<pre class="literal-block">
void <strong>set_name</strong> (std::string const&amp; n);
const std::string&amp; <strong>name</strong> () const;
</pre>
<p>set and get the name of this torrent. For multi-file torrents, this is also
the name of the root directory all the files are stored in.</p>
<a name="swap()"></a></div>
<div class="section" id="swap">
<h2>swap()</h2>
<pre class="literal-block">
void <strong>swap</strong> (file_storage&amp; ti);
</pre>
<p>swap all content of <em>this</em> with <em>ti</em>.</p>
<a name="optimize()"></a></div>
<div class="section" id="optimize">
<h2>optimize()</h2>
<pre class="literal-block">
void <strong>optimize</strong> (int pad_file_limit = -1, int alignment = 0x10000);
</pre>
<p>if pad_file_limit &gt;= 0, files larger than
that limit will be padded, default is to
not add any padding</p>
<a name="mtime()"></a>
<a name="hash()"></a>
<a name="symlink()"></a>
<a name="file_name()"></a>
<a name="pad_file_at()"></a>
<a name="file_size()"></a>
<a name="file_path()"></a>
<a name="file_offset()"></a></div>
<div class="section" id="mtime-hash-symlink-file-name-pad-file-at-file-size-file-path-file-offset">
<h2>mtime() hash() symlink() file_name() pad_file_at() file_size() file_path() file_offset()</h2>
<pre class="literal-block">
size_type <strong>file_size</strong> (int index) const;
sha1_hash <strong>hash</strong> (int index) const;
std::string <strong>file_name</strong> (int index) const;
size_type <strong>file_offset</strong> (int index) const;
time_t <strong>mtime</strong> (int index) const;
bool <strong>pad_file_at</strong> (int index) const;
std::string const&amp; <strong>symlink</strong> (int index) const;
std::string <strong>file_path</strong> (int index, std::string const&amp; save_path = &quot;&quot;) const;
</pre>
<p>These functions are used to query attributes of files at
a given index.</p>
<p>The <tt class="docutils literal">file_hash()</tt> is a sha-1 hash of the file, or 0 if none was
provided in the torrent file. This can potentially be used to
join a bittorrent network with other file sharing networks.</p>
<p>The <tt class="docutils literal">mtime()</tt> is the modification time is the posix
time when a file was last modified when the torrent
was created, or 0 if it was not included in the torrent file.</p>
<p><tt class="docutils literal">file_path()</tt> returns the full path to a file.</p>
<p><tt class="docutils literal">file_size()</tt> returns the size of a file.</p>
<p><tt class="docutils literal">pad_file_at()</tt> returns true if the file at the given
index is a pad-file.</p>
<p><tt class="docutils literal">file_name()</tt> returns <em>just</em> the name of the file, whereas
<tt class="docutils literal">file_path()</tt> returns the path (inside the torrent file) with
the filename appended.</p>
<p><tt class="docutils literal">file_offset()</tt> returns the byte offset within the torrent file
where this file starts. It can be used to map the file to a piece
index (given the piece size).</p>
<a name="file_flags()"></a></div>
<div class="section" id="file-flags">
<h2>file_flags()</h2>
<pre class="literal-block">
int <strong>file_flags</strong> (int index) const;
</pre>
<p>returns a bitmask of flags from <a class="reference external" href="reference-Storage.html#file_flags_t">file_flags_t</a> that apply
to file at <tt class="docutils literal">index</tt>.</p>
<a name="file_base()"></a>
<a name="set_file_base()"></a></div>
<div class="section" id="file-base-set-file-base">
<h2>file_base() set_file_base()</h2>
<pre class="literal-block">
void <strong>set_file_base</strong> (int index, size_type off);
size_type <strong>file_base</strong> (int index) const;
</pre>
<p>The file base of a file is the offset within the file on the filsystem
where it starts to write. For the most part, this is always 0. It's
possible to map several files (in the torrent) into a single file on
the filesystem by making them all point to the same filename, but with
different file bases, so that they don't overlap.
<a class="reference external" href="reference-Core.html#remap_files()">torrent_info::remap_files()</a> can be used to use a new file layout.</p>
<a name="file_index_at_offset()"></a></div>
<div class="section" id="file-index-at-offset">
<h2>file_index_at_offset()</h2>
<pre class="literal-block">
int <strong>file_index_at_offset</strong> (size_type offset) const;
</pre>
<p>returns the index of the file at the given offset in the torrent</p>
<a name="file_name_len()"></a>
<a name="file_name_ptr()"></a></div>
<div class="section" id="file-name-len-file-name-ptr">
<h2>file_name_len() file_name_ptr()</h2>
<pre class="literal-block">
char const* <strong>file_name_ptr</strong> (int index) const;
int <strong>file_name_len</strong> (int index) const;
</pre>
<p>low-level function. returns a pointer to the internal storage for
the filename. This string may not be null terinated!
the <tt class="docutils literal">file_name_len()</tt> function returns the length of the filename.</p>
<a name="flags_t"></a></div>
<div class="section" id="enum-flags-t">
<h2>enum flags_t</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/file_storage.hpp">libtorrent/file_storage.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="25%" />
<col width="8%" />
<col width="67%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>pad_file</td>
<td>1</td>
<td>the file is a pad file. It's required to contain zeroes
at it will not be saved to disk. Its purpose is to make
the following file start on a piece boundary.</td>
</tr>
<tr><td>attribute_hidden</td>
<td>2</td>
<td>this file has the hidden attribute set. This is primarily
a windows attribute</td>
</tr>
<tr><td>attribute_executable</td>
<td>4</td>
<td>this file has the executable attribute set.</td>
</tr>
<tr><td>attribute_symlink</td>
<td>8</td>
<td>this file is a symbilic link. It should have a link
target string associated with it.</td>
</tr>
</tbody>
</table>
<a name="file_flags_t"></a></div>
<div class="section" id="enum-file-flags-t">
<h2>enum file_flags_t</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/file_storage.hpp">libtorrent/file_storage.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="23%" />
<col width="9%" />
<col width="68%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>flag_pad_file</td>
<td>1</td>
<td>this file is a pad file. The creator of the
torrent promises the file is entirely filled with
zeroes and does not need to be downloaded. The
purpose is just to align the next file to either
a block or piece boundary.</td>
</tr>
<tr><td>flag_hidden</td>
<td>2</td>
<td>this file is hiddent (sets the hidden attribute
on windows)</td>
</tr>
<tr><td>flag_executable</td>
<td>4</td>
<td>this file is executable (sets the executable bit
on posix like systems)</td>
</tr>
<tr><td>flag_symlink</td>
<td>8</td>
<td>this file is a symlink. The symlink target is
specified in a separate field</td>
</tr>
</tbody>
</table>
<a name="default_storage_constructor()"></a></div>
<div class="section" id="default-storage-constructor">
<h2>default_storage_constructor()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/storage_defs.hpp">libtorrent/storage_defs.hpp</a>&quot;</p>
<pre class="literal-block">
storage_interface* <strong>default_storage_constructor</strong> (
file_storage const&amp;, file_storage const* mapped, std::string const&amp;, file_pool&amp;
, std::vector&lt;boost::uint8_t&gt; const&amp;);
</pre>
<p>the constructor function for the regular file storage. This is the
default value for <a class="reference external" href="reference-Session.html#storage">add_torrent_params::storage</a>.</p>
<a name="disabled_storage_constructor()"></a></div>
<div class="section" id="disabled-storage-constructor">
<h2>disabled_storage_constructor()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/storage_defs.hpp">libtorrent/storage_defs.hpp</a>&quot;</p>
<pre class="literal-block">
storage_interface* <strong>disabled_storage_constructor</strong> (
file_storage const&amp;, file_storage const* mapped, std::string const&amp;, file_pool&amp;
, std::vector&lt;boost::uint8_t&gt; const&amp;);
</pre>
<p>the constructor function for the disabled storage. This can be used for
testing and benchmarking. It will throw away any data written to
it and return garbage for anything read from it.</p>
<a name="storage_mode_t"></a></div>
<div class="section" id="enum-storage-mode-t">
<h2>enum storage_mode_t</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/storage_defs.hpp">libtorrent/storage_defs.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="22%" />
<col width="7%" />
<col width="72%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>storage_mode_allocate</td>
<td>0</td>
<td>All pieces will be written to their final position, all files will be
allocated in full when the torrent is first started. This is done with
<tt class="docutils literal">fallocate()</tt> and similar calls. This mode minimizes fragmentation.</td>
</tr>
<tr><td>storage_mode_sparse</td>
<td>1</td>
<td>All pieces will be written to the place where they belong and sparse files
will be used. This is the recommended, and default mode.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

169
docs/reference-String.html Normal file
View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>String</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="string">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">String</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#to-hex" id="id9">to_hex()</a></li>
<li><a class="reference internal" href="#id2" id="id10">to_hex()</a></li>
<li><a class="reference internal" href="#from-hex" id="id11">from_hex()</a></li>
<li><a class="reference internal" href="#is-digit" id="id12">is_digit()</a></li>
<li><a class="reference internal" href="#utf8-wchar-wchar-utf8" id="id13">utf8_wchar() wchar_utf8()</a></li>
<li><a class="reference internal" href="#enum-utf8-conv-result-t" id="id14">enum utf8_conv_result_t</a></li>
</ul>
</div>
<a name="to_hex()"></a><div class="section" id="to-hex">
<h1>to_hex()</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/escape_string.hpp">libtorrent/escape_string.hpp</a>&quot;</p>
<pre class="literal-block">
std::string <strong>to_hex</strong> (std::string const&amp; s);
</pre>
<p>converts (binary) the string <tt class="docutils literal">s</tt> to hexadecimal representation and
returns it.</p>
<a name="to_hex()"></a></div>
<div class="section" id="id2">
<h1>to_hex()</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/escape_string.hpp">libtorrent/escape_string.hpp</a>&quot;</p>
<pre class="literal-block">
void <strong>to_hex</strong> (char const <em>in, int len, char</em> out);
</pre>
<p>converts the binary buffer [<tt class="docutils literal">in</tt>, <tt class="docutils literal">in</tt> + len) to hexadecimal
and prints it to the buffer <tt class="docutils literal">out</tt>. The caller is responsible for
making sure the buffer pointed to by <tt class="docutils literal">out</tt> is large enough,
i.e. has at least len * 2 bytes of space.</p>
<a name="from_hex()"></a></div>
<div class="section" id="from-hex">
<h1>from_hex()</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/escape_string.hpp">libtorrent/escape_string.hpp</a>&quot;</p>
<pre class="literal-block">
bool <strong>from_hex</strong> (char const <em>in, int len, char</em> out);
</pre>
<p>converts the buffer [<tt class="docutils literal">in</tt>, <tt class="docutils literal">in</tt> + len) from hexadecimal to
binary. The binary output is written to the buffer pointed to
by <tt class="docutils literal">out</tt>. The caller is responsible for making sure the buffer
at <tt class="docutils literal">out</tt> has enough space for the result to be written to, i.e.
(len + 1) / 2 bytes.</p>
<a name="is_digit()"></a></div>
<div class="section" id="is-digit">
<h1>is_digit()</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/string_util.hpp">libtorrent/string_util.hpp</a>&quot;</p>
<pre class="literal-block">
bool <strong>is_digit</strong> (char c);
</pre>
<p>this is used by bdecode_recursive's header file</p>
<a name="utf8_wchar()"></a>
<a name="wchar_utf8()"></a></div>
<div class="section" id="utf8-wchar-wchar-utf8">
<h1>utf8_wchar() wchar_utf8()</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/utf8.hpp">libtorrent/utf8.hpp</a>&quot;</p>
<pre class="literal-block">
utf8_conv_result_t <strong>wchar_utf8</strong> (
const std::wstring &amp;wide, std::string &amp;utf8);
utf8_conv_result_t <strong>utf8_wchar</strong> (
const std::string &amp;utf8, std::wstring &amp;wide);
</pre>
<p><tt class="docutils literal">utf8_wchar</tt> converts a UTF-8 string (<tt class="docutils literal">utf8</tt>) to a wide character
string (<tt class="docutils literal">wide</tt>). <tt class="docutils literal">wchar_utf8</tt> converts a wide character string
(<tt class="docutils literal">wide</tt>) to a UTF-8 string (<tt class="docutils literal">utf8</tt>). The return value is one of
the enumeration values from <a class="reference external" href="reference-String.html#utf8_conv_result_t">utf8_conv_result_t</a>.</p>
<a name="utf8_conv_result_t"></a></div>
<div class="section" id="enum-utf8-conv-result-t">
<h1>enum utf8_conv_result_t</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/utf8.hpp">libtorrent/utf8.hpp</a>&quot;</p>
<table border="1" class="docutils">
<colgroup>
<col width="27%" />
<col width="10%" />
<col width="63%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">value</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>conversion_ok</td>
<td>0</td>
<td>conversion successful</td>
</tr>
<tr><td>source_exhausted</td>
<td>1</td>
<td>partial character in source, but hit end</td>
</tr>
<tr><td>target_exhausted</td>
<td>2</td>
<td>insuff. room in target for conversion</td>
</tr>
<tr><td>source_illegal</td>
<td>3</td>
<td>source sequence is illegal/malformed</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

197
docs/reference-Time.html Normal file
View File

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Time</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="time">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Time</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#time-duration" id="id17">time_duration</a></li>
<li><a class="reference internal" href="#ptime" id="id18">ptime</a></li>
</ul>
</div>
<p>This section contains fundamental time types used internall by
libtorrent and exposed through various places in the API. The two
basic types are <tt class="docutils literal">ptime</tt> and <tt class="docutils literal">time_duration</tt>. The first represents
a point in time and the second the difference between two points
in time.</p>
<p>The internal representation of these types is implementation defined
and they can only be constructed via one of the construction functions
that take a well defined time unit (seconds, minutes, etc.). They can
only be turned into well defined time units by the accessor functions
(total_microseconds(), etc.).</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">In a future version of libtorrent, these types will be replaced
by the standard timer types from <tt class="docutils literal"><span class="pre">std::chrono</span></tt>.</p>
</div>
<a name="time_duration"></a><div class="section" id="time-duration">
<h1>time_duration</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ptime.hpp">libtorrent/ptime.hpp</a>&quot;</p>
<p>libtorrent <a class="reference external" href="reference-Time.html#time_duration">time_duration</a> type</p>
<pre class="literal-block">
struct time_duration
{
time_duration&amp; <strong>operator-=</strong> (time_duration const&amp; c);
time_duration <strong>operator+</strong> (time_duration const&amp; c);
time_duration&amp; <strong>operator+=</strong> (time_duration const&amp; c);
time_duration <strong>operator/</strong> (int rhs) const;
explicit <strong>time_duration</strong> (boost::int64_t d);
time_duration <strong>operator-</strong> (time_duration const&amp; c);
time_duration&amp; <strong>operator*=</strong> (int v);
};
</pre>
<a name="ptime"></a></div>
<div class="section" id="ptime">
<h1>ptime</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ptime.hpp">libtorrent/ptime.hpp</a>&quot;</p>
<p>This type represents a point in time.</p>
<pre class="literal-block">
struct ptime
{
ptime&amp; <strong>operator-=</strong> (time_duration rhs);
ptime&amp; <strong>operator+=</strong> (time_duration rhs);
};
</pre>
<a name="is_negative()"></a><div class="section" id="is-negative">
<h2>is_negative()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ptime.hpp">libtorrent/ptime.hpp</a>&quot;</p>
<pre class="literal-block">
inline bool <strong>is_negative</strong> (time_duration dt);
</pre>
<a name="operator+()"></a>
<a name="operator-()"></a></div>
<div class="section" id="operator-operator">
<h2>operator+() operator-()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/ptime.hpp">libtorrent/ptime.hpp</a>&quot;</p>
<pre class="literal-block">
inline ptime <strong>operator+</strong> (time_duration lhs, ptime rhs);
inline ptime <strong>operator+</strong> (ptime lhs, time_duration rhs);
inline time_duration <strong>operator-</strong> (ptime lhs, ptime rhs);
inline ptime <strong>operator-</strong> (ptime lhs, time_duration rhs);
</pre>
<a name="time_now()"></a></div>
<div class="section" id="time-now">
<h2>time_now()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/time.hpp">libtorrent/time.hpp</a>&quot;</p>
<pre class="literal-block">
ptime const&amp; <strong>time_now</strong> ();
</pre>
<p>returns the current time, as represented by <a class="reference external" href="reference-Time.html#ptime">ptime</a>. The
resolution of this timer is about 100 ms.</p>
<a name="time_now_hires()"></a></div>
<div class="section" id="time-now-hires">
<h2>time_now_hires()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/time.hpp">libtorrent/time.hpp</a>&quot;</p>
<pre class="literal-block">
ptime <strong>time_now_hires</strong> ();
</pre>
<p>returns the current time as represented by <a class="reference external" href="reference-Time.html#ptime">ptime</a>. This is
more expensive than <a class="reference external" href="reference-Time.html#time_now()">time_now()</a>, but provides as high resolution
as the operating system can provide.</p>
<a name="min_time()"></a>
<a name="max_time()"></a></div>
<div class="section" id="min-time-max-time">
<h2>min_time() max_time()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/time.hpp">libtorrent/time.hpp</a>&quot;</p>
<pre class="literal-block">
ptime <strong>max_time</strong> ();
ptime <strong>min_time</strong> ();
</pre>
<p>the earliest and latest possible time points
representable by <a class="reference external" href="reference-Time.html#ptime">ptime</a>.</p>
<a name="microsec()"></a>
<a name="minutes()"></a>
<a name="hours()"></a>
<a name="milliseconds()"></a>
<a name="seconds()"></a></div>
<div class="section" id="microsec-minutes-hours-milliseconds-seconds">
<h2>microsec() minutes() hours() milliseconds() seconds()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/time.hpp">libtorrent/time.hpp</a>&quot;</p>
<pre class="literal-block">
time_duration <strong>microsec</strong> (boost::int64_t s);
time_duration <strong>seconds</strong> (boost::int64_t s);
time_duration <strong>milliseconds</strong> (boost::int64_t s);
time_duration <strong>minutes</strong> (boost::int64_t s);
time_duration <strong>hours</strong> (boost::int64_t s);
</pre>
<p>returns a <a class="reference external" href="reference-Time.html#time_duration">time_duration</a> representing the specified number of seconds, milliseconds
microseconds, minutes and hours.</p>
<a name="total_seconds()"></a>
<a name="total_microseconds()"></a>
<a name="total_milliseconds()"></a></div>
<div class="section" id="total-seconds-total-microseconds-total-milliseconds">
<h2>total_seconds() total_microseconds() total_milliseconds()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/time.hpp">libtorrent/time.hpp</a>&quot;</p>
<pre class="literal-block">
boost::int64_t <strong>total_seconds</strong> (time_duration td);
boost::int64_t <strong>total_milliseconds</strong> (time_duration td);
boost::int64_t <strong>total_microseconds</strong> (time_duration td);
</pre>
<p>returns the number of seconds, milliseconds and microseconds
a <a class="reference external" href="reference-Time.html#time_duration">time_duration</a> represents.</p>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

426
docs/reference-Utility.html Normal file
View File

@ -0,0 +1,426 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>Utility</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="utility">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">Utility</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>1.0.0</td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<ul class="simple">
<li><a class="reference internal" href="#bitfield" id="id35">bitfield</a></li>
<li><a class="reference internal" href="#sha1-hash" id="id36">sha1_hash</a></li>
</ul>
</div>
<a name="bitfield"></a><div class="section" id="bitfield">
<h1>bitfield</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/bitfield.hpp">libtorrent/bitfield.hpp</a>&quot;</p>
<p>The bitfiled type stores any number of bits as a <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>
in a heap allocated or borrowed array.</p>
<pre class="literal-block">
struct bitfield
{
<strong>bitfield</strong> (int bits, bool val);
<strong>bitfield</strong> ();
<strong>bitfield</strong> (int bits);
<strong>bitfield</strong> (bitfield const&amp; rhs);
<strong>bitfield</strong> (char const* b, int bits);
<strong>bitfield</strong> (bitfield&amp;&amp; rhs);
void <strong>borrow_bytes</strong> (char* b, int bits);
void <strong>assign</strong> (char const* b, int bits);
bool <strong>get_bit</strong> (int index) const;
bool <strong>operator[]</strong> (int index) const;
void <strong>clear_bit</strong> (int index);
void <strong>set_bit</strong> (int index);
bool <strong>all_set</strong> () const;
std::size_t <strong>size</strong> () const;
bool <strong>empty</strong> () const;
char const* <strong>bytes</strong> () const;
bitfield&amp; <strong>operator=</strong> (bitfield const&amp; rhs);
int <strong>count</strong> () const;
};
</pre>
<a name="bitfield()"></a><div class="section" id="id3">
<h2>bitfield()</h2>
<pre class="literal-block">
<strong>bitfield</strong> (int bits, bool val);
<strong>bitfield</strong> ();
<strong>bitfield</strong> (int bits);
<strong>bitfield</strong> (bitfield const&amp; rhs);
<strong>bitfield</strong> (char const* b, int bits);
</pre>
<p>constructs a new <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>. The default constructor creates an empty
<a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>. <tt class="docutils literal">bits</tt> is the size of the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> (specified in bits).
`` val`` is the value to initialize the bits to. If not specified
all bits are initialized to 0.</p>
<p>The constructor taking a pointer <tt class="docutils literal">b</tt> and <tt class="docutils literal">bits</tt> copies a <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>
from the specified buffer, and <tt class="docutils literal">bits</tt> number of bits (rounded up to
the nearest byte boundry).</p>
<a name="borrow_bytes()"></a></div>
<div class="section" id="borrow-bytes">
<h2>borrow_bytes()</h2>
<pre class="literal-block">
void <strong>borrow_bytes</strong> (char* b, int bits);
</pre>
<p>assigns a <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> pointed to <tt class="docutils literal">b</tt> of <tt class="docutils literal">bits</tt> number of bits, without
taking ownership of the buffer. This is a way to avoid copying data and
yet provide a raw buffer to functions that may operate on the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>
type. It is the user's responsibility to make sure the passed-in buffer's
life time exceeds all uses of the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>.</p>
<a name="assign()"></a></div>
<div class="section" id="assign">
<h2>assign()</h2>
<pre class="literal-block">
void <strong>assign</strong> (char const* b, int bits);
</pre>
<p>copy <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> from buffer <tt class="docutils literal">b</tt> of <tt class="docutils literal">bits</tt> number of bits, rounded up to
the nearest byte boundary.</p>
<a name="operator[]()"></a>
<a name="get_bit()"></a></div>
<div class="section" id="operator-get-bit">
<h2>operator[]() get_bit()</h2>
<pre class="literal-block">
bool <strong>get_bit</strong> (int index) const;
bool <strong>operator[]</strong> (int index) const;
</pre>
<p>query bit at <tt class="docutils literal">index</tt>. Returns true if bit is 1, otherwise false.</p>
<a name="set_bit()"></a>
<a name="clear_bit()"></a></div>
<div class="section" id="set-bit-clear-bit">
<h2>set_bit() clear_bit()</h2>
<pre class="literal-block">
void <strong>clear_bit</strong> (int index);
void <strong>set_bit</strong> (int index);
</pre>
<p>set bit at <tt class="docutils literal">index</tt> to 0 (clear_bit) or 1 (set_bit).</p>
<a name="all_set()"></a></div>
<div class="section" id="all-set">
<h2>all_set()</h2>
<pre class="literal-block">
bool <strong>all_set</strong> () const;
</pre>
<p>returns true if all bits in the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> are set</p>
<a name="size()"></a></div>
<div class="section" id="size">
<h2>size()</h2>
<pre class="literal-block">
std::size_t <strong>size</strong> () const;
</pre>
<p>returns the size of the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> in bits.</p>
<a name="empty()"></a></div>
<div class="section" id="empty">
<h2>empty()</h2>
<pre class="literal-block">
bool <strong>empty</strong> () const;
</pre>
<p>returns true if the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> has zero size.</p>
<a name="bytes()"></a></div>
<div class="section" id="bytes">
<h2>bytes()</h2>
<pre class="literal-block">
char const* <strong>bytes</strong> () const;
</pre>
<p>returns a pointer to the internal buffer of the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a>.</p>
<a name="operator=()"></a></div>
<div class="section" id="operator">
<h2>operator=()</h2>
<pre class="literal-block">
bitfield&amp; <strong>operator=</strong> (bitfield const&amp; rhs);
</pre>
<p>copy operator</p>
<a name="count()"></a></div>
<div class="section" id="count">
<h2>count()</h2>
<pre class="literal-block">
int <strong>count</strong> () const;
</pre>
<p>count the number of bits in the <a class="reference external" href="reference-Utility.html#bitfield">bitfield</a> that are set to 1.</p>
<a name="sha1_hash"></a></div>
</div>
<div class="section" id="sha1-hash">
<h1>sha1_hash</h1>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/sha1_hash.hpp">libtorrent/sha1_hash.hpp</a>&quot;</p>
<p>This type holds a SHA-1 digest or any other kind of 20 byte
sequence. It implements a number of convenience functions, such
as bit operations, comparison operators etc.</p>
<p>In libtorrent it is primarily used to hold info-hashes, piece-hashes,
peer IDs, node IDs etc.</p>
<pre class="literal-block">
class sha1_hash
{
<strong>sha1_hash</strong> ();
static sha1_hash <strong>max</strong> ();
static sha1_hash <strong>min</strong> ();
explicit <strong>sha1_hash</strong> (char const* s);
void <strong>assign</strong> (char const* str);
explicit <strong>sha1_hash</strong> (std::string const&amp; s);
void <strong>assign</strong> (std::string const&amp; s);
void <strong>clear</strong> ();
bool <strong>is_all_zeros</strong> () const;
sha1_hash&amp; <strong>operator&lt;&lt;=</strong> (int n);
sha1_hash&amp; <strong>operator&gt;&gt;=</strong> (int n);
bool <strong>operator==</strong> (sha1_hash const&amp; n) const;
bool <strong>operator!=</strong> (sha1_hash const&amp; n) const;
bool <strong>operator&lt;</strong> (sha1_hash const&amp; n) const;
sha1_hash <strong>operator~</strong> ();
sha1_hash <strong>operator^</strong> (sha1_hash const&amp; n) const;
sha1_hash&amp; <strong>operator^=</strong> (sha1_hash const&amp; n);
sha1_hash <strong>operator&amp;</strong> (sha1_hash const&amp; n) const;
sha1_hash&amp; <strong>operator&amp;=</strong> (sha1_hash const&amp; n);
sha1_hash&amp; <strong>operator|=</strong> (sha1_hash const&amp; n);
unsigned char&amp; <strong>operator[]</strong> (int i);
unsigned char const&amp; <strong>operator[]</strong> (int i) const;
const_iterator <strong>begin</strong> () const;
iterator <strong>begin</strong> ();
iterator <strong>end</strong> ();
const_iterator <strong>end</strong> () const;
std::string <strong>to_string</strong> () const;
static const int size = number_size;
};
</pre>
<a name="sha1_hash()"></a><div class="section" id="id18">
<h2>sha1_hash()</h2>
<pre class="literal-block">
<strong>sha1_hash</strong> ();
</pre>
<p>constructs an all-sero sha1-hash</p>
<a name="max()"></a></div>
<div class="section" id="max">
<h2>max()</h2>
<pre class="literal-block">
static sha1_hash <strong>max</strong> ();
</pre>
<p>returns an all-F sha1-hash. i.e. the maximum value
representable by a 160 bit number (20 bytes). This is
a static member function.</p>
<a name="min()"></a></div>
<div class="section" id="min">
<h2>min()</h2>
<pre class="literal-block">
static sha1_hash <strong>min</strong> ();
</pre>
<p>returns an all-zero sha1-hash. i.e. the minimum value
representable by a 160 bit number (20 bytes). This is
a static member function.</p>
<a name="assign()"></a>
<a name="sha1_hash()"></a></div>
<div class="section" id="assign-sha1-hash">
<h2>assign() sha1_hash()</h2>
<pre class="literal-block">
explicit <strong>sha1_hash</strong> (char const* s);
void <strong>assign</strong> (char const* str);
explicit <strong>sha1_hash</strong> (std::string const&amp; s);
void <strong>assign</strong> (std::string const&amp; s);
</pre>
<p>copies 20 bytes from the pointer provided, into the sha1-hash.
The passed in string MUST be at least 20 bytes. NULL terminators
are ignored, <tt class="docutils literal">s</tt> is treated like a raw memory buffer.</p>
<a name="clear()"></a></div>
<div class="section" id="clear">
<h2>clear()</h2>
<pre class="literal-block">
void <strong>clear</strong> ();
</pre>
<p>set the sha1-hash to all zeroes.</p>
<a name="is_all_zeros()"></a></div>
<div class="section" id="is-all-zeros">
<h2>is_all_zeros()</h2>
<pre class="literal-block">
bool <strong>is_all_zeros</strong> () const;
</pre>
<p>return true if the sha1-hash is all zero.</p>
<a name="operator<<=()"></a></div>
<div class="section" id="id19">
<h2>operator&lt;&lt;=()</h2>
<pre class="literal-block">
sha1_hash&amp; <strong>operator&lt;&lt;=</strong> (int n);
</pre>
<p>shift left <tt class="docutils literal">n</tt> bits.</p>
<a name="operator>>=()"></a></div>
<div class="section" id="id20">
<h2>operator&gt;&gt;=()</h2>
<pre class="literal-block">
sha1_hash&amp; <strong>operator&gt;&gt;=</strong> (int n);
</pre>
<p>shift r <tt class="docutils literal">n</tt> bits.</p>
<a name="operator==()"></a></div>
<div class="section" id="id21">
<h2>operator==()</h2>
<pre class="literal-block">
bool <strong>operator==</strong> (sha1_hash const&amp; n) const;
</pre>
<p>standard comparison operators</p>
<a name="operator~()"></a></div>
<div class="section" id="id22">
<h2>operator~()</h2>
<pre class="literal-block">
sha1_hash <strong>operator~</strong> ();
</pre>
<p>negate every bit in the sha1-hash</p>
<a name="operator^=()"></a>
<a name="operator^()"></a></div>
<div class="section" id="operator-operator">
<h2>operator^=() operator^()</h2>
<pre class="literal-block">
sha1_hash <strong>operator^</strong> (sha1_hash const&amp; n) const;
sha1_hash&amp; <strong>operator^=</strong> (sha1_hash const&amp; n);
</pre>
<p>bit-wise XOR of the two sha1-hash.</p>
<a name="operator&=()"></a>
<a name="operator&()"></a></div>
<div class="section" id="id23">
<h2>operator&amp;=() operator&amp;()</h2>
<pre class="literal-block">
sha1_hash <strong>operator&amp;</strong> (sha1_hash const&amp; n) const;
sha1_hash&amp; <strong>operator&amp;=</strong> (sha1_hash const&amp; n);
</pre>
<p>bit-wise AND of the two sha1-hash.</p>
<a name="operator|=()"></a></div>
<div class="section" id="id24">
<h2>operator|=()</h2>
<pre class="literal-block">
sha1_hash&amp; <strong>operator|=</strong> (sha1_hash const&amp; n);
</pre>
<p>bit-wise OR of the two sha1-hash.</p>
<a name="operator[]()"></a></div>
<div class="section" id="id25">
<h2>operator[]()</h2>
<pre class="literal-block">
unsigned char&amp; <strong>operator[]</strong> (int i);
unsigned char const&amp; <strong>operator[]</strong> (int i) const;
</pre>
<p>accessors for specific bytes</p>
<a name="begin()"></a>
<a name="end()"></a></div>
<div class="section" id="begin-end">
<h2>begin() end()</h2>
<pre class="literal-block">
const_iterator <strong>begin</strong> () const;
iterator <strong>begin</strong> ();
iterator <strong>end</strong> ();
const_iterator <strong>end</strong> () const;
</pre>
<p>start and end iterators for the hash. The value type
of these iterators is <tt class="docutils literal">unsigned char</tt>.</p>
<a name="to_string()"></a></div>
<div class="section" id="to-string">
<h2>to_string()</h2>
<pre class="literal-block">
std::string <strong>to_string</strong> () const;
</pre>
<p>return a copy of the 20 bytes representing the sha1-hash as a std::string.
It's still a binary string with 20 binary characters.</p>
<a name="number_size"></a><dl class="docutils">
<dt>number_size</dt>
<dd>the number of bytes of the number</dd>
</dl>
<a name="identify_client()"></a></div>
<div class="section" id="identify-client">
<h2>identify_client()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/identify_client.hpp">libtorrent/identify_client.hpp</a>&quot;</p>
<pre class="literal-block">
std::string <strong>identify_client</strong> (const peer_id&amp; p);
</pre>
<p>This function is declared in the header <tt class="docutils literal">&lt;libtorrent/identify_client.hpp&gt;</tt>. It can can be used
to extract a string describing a client version from its peer-id. It will recognize most clients
that have this kind of identification in the peer-id.</p>
<a name="client_fingerprint()"></a></div>
<div class="section" id="client-fingerprint">
<h2>client_fingerprint()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/identify_client.hpp">libtorrent/identify_client.hpp</a>&quot;</p>
<pre class="literal-block">
boost::optional&lt;fingerprint&gt; <strong>client_fingerprint</strong> (peer_id const&amp; p);
</pre>
<p>Returns an optional fingerprint if any can be identified from the peer id. This can be used
to automate the identification of clients. It will not be able to identify peers with non-
standard encodings. Only Azureus style, Shadow's style and Mainline style. This function is
declared in the header <tt class="docutils literal">&lt;libtorrent/identify_client.hpp&gt;</tt>.</p>
<a name="operator<<()"></a></div>
<div class="section" id="id28">
<h2>operator&lt;&lt;()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/sha1_hash.hpp">libtorrent/sha1_hash.hpp</a>&quot;</p>
<pre class="literal-block">
inline std::ostream&amp; <strong>operator&lt;&lt;</strong> (std::ostream&amp; os, sha1_hash const&amp; peer);
</pre>
<p>print a <a class="reference external" href="reference-Utility.html#sha1_hash">sha1_hash</a> object to an ostream as 40 hexadecimal digits</p>
<a name="operator>>()"></a></div>
<div class="section" id="id31">
<h2>operator&gt;&gt;()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/sha1_hash.hpp">libtorrent/sha1_hash.hpp</a>&quot;</p>
<pre class="literal-block">
inline std::istream&amp; <strong>operator&gt;&gt;</strong> (std::istream&amp; is, sha1_hash&amp; peer);
</pre>
<p>read 40 hexadecimal digits from an istream into a <a class="reference external" href="reference-Utility.html#sha1_hash">sha1_hash</a></p>
<a name="sleep()"></a></div>
<div class="section" id="sleep">
<h2>sleep()</h2>
<p>Declared in &quot;<a class="reference external" href="../include/libtorrent/thread.hpp">libtorrent/thread.hpp</a>&quot;</p>
<pre class="literal-block">
void <strong>sleep</strong> (int milliseconds);
</pre>
<p>pauses the calling thread at least for the specified
number of milliseconds</p>
</div>
</div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

318
docs/reference.html Normal file
View File

@ -0,0 +1,318 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
<title>libtorrent reference documentation</title>
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
<script type="text/javascript">
/* <![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
</style>
</head>
<body>
<div class="document" id="libtorrent-reference-documentation">
<div id="container">
<div id="headerNav">
<ul>
<li class="first"><a href="/">Home</a></li>
<li><a href="../../products.html">Products</a></li>
<li><a href="../../contact.html">Contact</a></li>
</ul>
</div>
<div id="header">
<div id="orange"></div>
<div id="logo"></div>
</div>
<div id="main">
<h1 class="title">libtorrent reference documentation</h1>
<div style="column-count: 4; -webkit-column-count: 4; -moz-column-count: 4"><div class="section" id="custom-storage">
<h1>Custom Storage</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Custom_Storage.html#overview">overview</a></div>
<div class="line"><a class="reference external" href="reference-Custom_Storage.html#file_pool">file_pool</a></div>
<div class="line"><a class="reference external" href="reference-Custom_Storage.html#storage_interface">storage_interface</a></div>
<div class="line"><a class="reference external" href="reference-Custom_Storage.html#default_storage">default_storage</a></div>
<div class="line"><a class="reference external" href="reference-Custom_Storage.html#move_flags_t">move_flags_t</a></div>
</div>
</div>
<div class="section" id="core">
<h1>Core</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Core.html#disk_buffer_holder">disk_buffer_holder</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#peer_info">peer_info</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#peer_list_entry">peer_list_entry</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#peer_request">peer_request</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#piece_block_progress">piece_block_progress</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#block_info">block_info</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#partial_piece_info">partial_piece_info</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#torrent_handle">torrent_handle</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#torrent_status">torrent_status</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#announce_entry">announce_entry</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#torrent_info">torrent_info</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#make_magnet_uri()">make_magnet_uri()</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#parse_magnet_uri()">parse_magnet_uri()</a></div>
<div class="line"><a class="reference external" href="reference-Core.html#hash_value()">hash_value()</a></div>
</div>
</div>
<div class="section" id="time">
<h1>Time</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Time.html#overview">overview</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#time_duration">time_duration</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#ptime">ptime</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#is_negative()">is_negative()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#operator+()">operator+()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#operator-()">operator-()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#time_now()">time_now()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#time_now_hires()">time_now_hires()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#min_time()">min_time()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#max_time()">max_time()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#microsec()">microsec()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#minutes()">minutes()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#hours()">hours()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#milliseconds()">milliseconds()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#seconds()">seconds()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#total_seconds()">total_seconds()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#total_microseconds()">total_microseconds()</a></div>
<div class="line"><a class="reference external" href="reference-Time.html#total_milliseconds()">total_milliseconds()</a></div>
</div>
</div>
<div class="section" id="bencoding">
<h1>Bencoding</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Bencoding.html#overview">overview</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#invalid_encoding">invalid_encoding</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#type_error">type_error</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#entry">entry</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#pascal_string">pascal_string</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#lazy_entry">lazy_entry</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#bdecode()">bdecode()</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#bencode()">bencode()</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#operator&lt;&lt;()">operator&lt;&lt;()</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#lazy_bdecode()">lazy_bdecode()</a></div>
<div class="line"><a class="reference external" href="reference-Bencoding.html#get_bdecode_category()">get_bdecode_category()</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#error_code_enum">error_code_enum</a></div>
</div>
</div>
<div class="section" id="string">
<h1>String</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-String.html#to_hex()">to_hex()</a></div>
<div class="line"><a class="reference external" href="reference-String.html#to_hex()">to_hex()</a></div>
<div class="line"><a class="reference external" href="reference-String.html#from_hex()">from_hex()</a></div>
<div class="line"><a class="reference external" href="reference-String.html#is_digit()">is_digit()</a></div>
<div class="line"><a class="reference external" href="reference-String.html#utf8_wchar()">utf8_wchar()</a></div>
<div class="line"><a class="reference external" href="reference-String.html#wchar_utf8()">wchar_utf8()</a></div>
<div class="line"><a class="reference external" href="reference-String.html#utf8_conv_result_t">utf8_conv_result_t</a></div>
</div>
</div>
<div class="section" id="settings">
<h1>Settings</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Settings.html#proxy_settings">proxy_settings</a></div>
<div class="line"><a class="reference external" href="reference-Settings.html#session_settings">session_settings</a></div>
</div>
</div>
<div class="section" id="plugins">
<h1>Plugins</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Plugins.html#overview">overview</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#plugin">plugin</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#torrent_plugin">torrent_plugin</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#peer_plugin">peer_plugin</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#create_lt_trackers_plugin()">create_lt_trackers_plugin()</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#create_smart_ban_plugin()">create_smart_ban_plugin()</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#create_ut_metadata_plugin()">create_ut_metadata_plugin()</a></div>
<div class="line"><a class="reference external" href="reference-Plugins.html#create_ut_pex_plugin()">create_ut_pex_plugin()</a></div>
</div>
</div>
<div class="section" id="alerts">
<h1>Alerts</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Alerts.html#overview">overview</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#alert">alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_alert">torrent_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_alert">peer_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#tracker_alert">tracker_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_added_alert">torrent_added_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_removed_alert">torrent_removed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#read_piece_alert">read_piece_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#file_completed_alert">file_completed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#file_renamed_alert">file_renamed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#file_rename_failed_alert">file_rename_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#performance_alert">performance_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#state_changed_alert">state_changed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#tracker_error_alert">tracker_error_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#tracker_warning_alert">tracker_warning_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#scrape_reply_alert">scrape_reply_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#scrape_failed_alert">scrape_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#tracker_reply_alert">tracker_reply_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#dht_reply_alert">dht_reply_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#tracker_announce_alert">tracker_announce_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#hash_failed_alert">hash_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_ban_alert">peer_ban_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_unsnubbed_alert">peer_unsnubbed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_snubbed_alert">peer_snubbed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_error_alert">peer_error_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_connect_alert">peer_connect_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_disconnected_alert">peer_disconnected_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#invalid_request_alert">invalid_request_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_finished_alert">torrent_finished_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#piece_finished_alert">piece_finished_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#request_dropped_alert">request_dropped_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#block_timeout_alert">block_timeout_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#block_finished_alert">block_finished_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#block_downloading_alert">block_downloading_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#unwanted_block_alert">unwanted_block_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#storage_moved_alert">storage_moved_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#storage_moved_failed_alert">storage_moved_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_deleted_alert">torrent_deleted_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_delete_failed_alert">torrent_delete_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#save_resume_data_alert">save_resume_data_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#save_resume_data_failed_alert">save_resume_data_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_paused_alert">torrent_paused_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_resumed_alert">torrent_resumed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_checked_alert">torrent_checked_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#url_seed_alert">url_seed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#file_error_alert">file_error_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#metadata_failed_alert">metadata_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#metadata_received_alert">metadata_received_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#udp_error_alert">udp_error_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#external_ip_alert">external_ip_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#listen_failed_alert">listen_failed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#listen_succeeded_alert">listen_succeeded_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#portmap_error_alert">portmap_error_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#portmap_alert">portmap_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#portmap_log_alert">portmap_log_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#fastresume_rejected_alert">fastresume_rejected_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#peer_blocked_alert">peer_blocked_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#dht_announce_alert">dht_announce_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#dht_get_peers_alert">dht_get_peers_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#stats_alert">stats_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#cache_flushed_alert">cache_flushed_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#anonymous_mode_alert">anonymous_mode_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#lsd_peer_alert">lsd_peer_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#trackerid_alert">trackerid_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#dht_bootstrap_alert">dht_bootstrap_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#rss_alert">rss_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_error_alert">torrent_error_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_need_cert_alert">torrent_need_cert_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#incoming_connection_alert">incoming_connection_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#add_torrent_alert">add_torrent_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#state_update_alert">state_update_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#torrent_update_alert">torrent_update_alert</a></div>
<div class="line"><a class="reference external" href="reference-Alerts.html#rss_item_alert">rss_item_alert</a></div>
</div>
</div>
<div class="section" id="storage">
<h1>Storage</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Storage.html#file_entry">file_entry</a></div>
<div class="line"><a class="reference external" href="reference-Storage.html#file_slice">file_slice</a></div>
<div class="line"><a class="reference external" href="reference-Storage.html#file_storage">file_storage</a></div>
<div class="line"><a class="reference external" href="reference-Storage.html#default_storage_constructor()">default_storage_constructor()</a></div>
<div class="line"><a class="reference external" href="reference-Storage.html#disabled_storage_constructor()">disabled_storage_constructor()</a></div>
<div class="line"><a class="reference external" href="reference-Storage.html#storage_mode_t">storage_mode_t</a></div>
</div>
</div>
<div class="section" id="filter">
<h1>Filter</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Filter.html#ip_filter">ip_filter</a></div>
<div class="line"><a class="reference external" href="reference-Filter.html#port_filter">port_filter</a></div>
</div>
</div>
<div class="section" id="session">
<h1>Session</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Session.html#add_torrent_params">add_torrent_params</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#cache_status">cache_status</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#session_proxy">session_proxy</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#session">session</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#dht_lookup">dht_lookup</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#dht_routing_bucket">dht_routing_bucket</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#utp_status">utp_status</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#session_status">session_status</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#min_memory_usage()">min_memory_usage()</a></div>
<div class="line"><a class="reference external" href="reference-Session.html#high_performance_seed()">high_performance_seed()</a></div>
</div>
</div>
<div class="section" id="create-torrents">
<h1>Create Torrents</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Create_Torrents.html#overview">overview</a></div>
<div class="line"><a class="reference external" href="reference-Create_Torrents.html#create_torrent">create_torrent</a></div>
<div class="line"><a class="reference external" href="reference-Create_Torrents.html#add_files()">add_files()</a></div>
<div class="line"><a class="reference external" href="reference-Create_Torrents.html#set_piece_hashes()">set_piece_hashes()</a></div>
</div>
</div>
<div class="section" id="error-codes">
<h1>Error Codes</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Error_Codes.html#http_error_category">http_error_category</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#libtorrent_exception">libtorrent_exception</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#i2p_error_category">i2p_error_category</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#upnp_error_category">upnp_error_category</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#get_libtorrent_category()">get_libtorrent_category()</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#get_http_category()">get_http_category()</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#error_code_enum">error_code_enum</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#http_errors">http_errors</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#i2p_error_code">i2p_error_code</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#socks_error_code">socks_error_code</a></div>
<div class="line"><a class="reference external" href="reference-Error_Codes.html#error_code_enum">error_code_enum</a></div>
</div>
</div>
<div class="section" id="rss">
<h1>RSS</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-RSS.html#feed_item">feed_item</a></div>
<div class="line"><a class="reference external" href="reference-RSS.html#feed_settings">feed_settings</a></div>
<div class="line"><a class="reference external" href="reference-RSS.html#feed_status">feed_status</a></div>
<div class="line"><a class="reference external" href="reference-RSS.html#feed_handle">feed_handle</a></div>
<div class="line"><a class="reference external" href="reference-RSS.html#add_feed_item()">add_feed_item()</a></div>
<div class="line"><a class="reference external" href="reference-RSS.html#new_feed()">new_feed()</a></div>
</div>
</div>
<div class="section" id="utility">
<h1>Utility</h1>
<div class="line-block">
<div class="line"><a class="reference external" href="reference-Utility.html#bitfield">bitfield</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#sha1_hash">sha1_hash</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#identify_client()">identify_client()</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#client_fingerprint()">client_fingerprint()</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#operator&lt;&lt;()">operator&lt;&lt;()</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#operator&gt;&gt;()">operator&gt;&gt;()</a></div>
<div class="line"><a class="reference external" href="reference-Utility.html#sleep()">sleep()</a></div>
</div>
</div></div>
</div>
<div id="footer">
<span>Copyright &copy; 2005-2013 Rasterbar Software.</span>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1599045-1";
urchinTracker();
</script>
</div>
</body>
</html>

245
docs/rst.css Normal file
View File

@ -0,0 +1,245 @@
.document {
margin-left: 10px;
margin-right: 10px;
}
.document a {
border: none;
color: black;
}
.document a:hover {
background: none;
}
.document a.reference {
color: #8D370A;
border-bottom: dotted 1px #8D370A;
}
.document a.reference:hover {
border-bottom: solid 1px #8D370A;
background: #eee;
}
div.section {
margin-bottom: 3em;
}
div.section div.section div.section {
margin-bottom: 2em;
}
h3 { text-transform: uppercase; }
div.section p, div.section ul, div.section dl {
}
table.docinfo {
text-align: left;
float: right;
width: 200px;
margin-right: 0px;
margin-left: 20px;
margin-bottom: 20px;
}
table.docinfo th {
border-top: none;
font-size: 72%;
padding-left: 10px;
}
table.docinfo td {
padding-left: 10px;
font-size: 88%;
}
table.docinfo tr.field td, table.docinfo tr.field th {display: none;}
h1.title { display: none; }
dt {
font-size: 100%;
letter-spacing: 2px;
line-height: 1em;
color: #315586;
color: #000;
font-family: Tahoma;
font-weight: bold;
}
dd {
line-height: 1.5em;
margin-left: 1em;
margin-bottom: 1em;
font-size: 92%;
}
tt {
font: 1em "Courier New", "Courier";
color: #315566;
}
pre {
font-family: "Courier", monospace;
margin-right: 10px;
background: #C1E5F6;
border-left: solid 2px #6185A6;
border-right: solid 2px #6185A6;
padding: 5px 10px 5px 10px;
background: #f6f6f6;
border: solid 1px #ddd;
margin: 1em 0;
}
div.warning, div.note, div.important {
width: 80%;
margin: 1.5em auto;
background: #C1E5F6;
background: #F1FFF5;
border: solid 1px #D1DFD5;
padding: 5px 10px 5px 10px;
}
p.admonition-title {
font-family: Georgia, "Lucida Grande";
font-size: 128%;
letter-spacing: 2px;
text-transform: uppercase;
margin: 0 0 0.5em 0;
border-bottom: solid 1px #D1DFD5
}
div.sidebar {
background: #f8f8e8;
float: right;
width: 20em;
margin-right: 1em;
border: solid 1px #e5e5d5;
padding: 1.3em;
}
div.sidebar p.sidebar-title {
font: 1.3em Georgia;
border-bottom: solid 1px #e5e5d5;
padding-bottom: 0.5em;
margin: 0 0 0.5em 0;
}
h1 { font-size: 230%; }
h2 { font-size: 180%; }
h3 { font-size: 130%; }
table { margin-bottom: 1em; border-collapse: collapse; }
table, th, td { border: none; }
th, td { padding: 0.3em; }
th {
text-align: left;
background: #f0f0e0;
border-right: solid 1px #f0f0e0;
border-top: solid 1px #e8e8d8;
border-bottom: solid 1px #e8e8d8;
}
td {
background: #f8f8e8;
border-right: solid 1px #f8f8e8;
border-bottom: solid 1px #e8e8d8;
}
td td {
background: #e8e8d8;
border-right: solid 1px #e8e8d8;
border-bottom: solid 1px #d8d8c8;
}
div.topic {
border-left: solid 1px #eee;
padding-left: 1em;
margin: 0 0 1.5em;
}
p.topic-title {
font: 1.3em Georgia, "Times New Roman", serif;
}
/* TOC */
div.contents {
border: none;
}
#table-of-contents {
margin-left: 20px;
padding: 0 0 1em;
width: 200px;
float: right;
clear: right;
background: url(../img/blue_bottom.png) no-repeat bottom left;
border-right: solid 1px #A1C5D6;
}
#table-of-contents p {
font-family: Georgia, "Times New Roman", serif;
background: #A1C5D6 url(../img/blue_top.png) no-repeat top left;
color: #AD370A;
padding: 0.5em;
margin: 0;
}
#table-of-contents li {
margin: 0 0.5em 0 0.5em;
}
#table-of-contents ul {
margin: 0;
padding: 0 0 0 0.8em;
list-style: none;
text-align: left;
line-height: 1.5em;
}
#table-of-contents ul ul {
background: url(../img/dotline.gif) repeat-y;
}
#table-of-contents a.reference {
border: none;
font: 0.88em Tahoma;
font-weight: bold;
color: #000050;
margin-right: 1em;
background: url(../img/minus.gif) no-repeat left 50%;
padding-left: 15px;
}
#table-of-contents li li a.reference {
font-weight: normal;
background: none;
padding: 0;
}
#table-of-contents a.reference:hover {text-decoration: underline;}
dd p {
font-size: 100%;
}
dd pre {
font-size: 108.7%;
}
li p, li li { font-size: 100%; }
/* IE Hacks */
/* Hides from IE-mac \*/
* html li pre { height: 1%; }
* html .topic pre { height: 1%; }
* html #table-of-contents ul ul { height: 1%; }
/* End hide from IE-mac */

View File

@ -21,10 +21,10 @@
</head><body>
<h1>libtorrent todo-list</h1>
<span style="color: #f77">3 important</span>
<span style="color: #f77">4 important</span>
<span style="color: #3c3">5 relevant</span>
<span style="color: #77f">15 feasible</span>
<span style="color: #999">41 notes</span>
<span style="color: #999">40 notes</span>
<table width="100%" border="1" style="border-collapse: collapse;"><tr style="background: #fdd"><td>relevance&nbsp;4</td><td><a href="javascript:expand(0)">../src/session_impl.cpp:663</a></td><td>in order to support SSL over uTP, the utp_socket manager either needs to be able to receive packets on multiple ports, or we need to peek into the first few bytes the payload stream of a socket to determine whether or not it's an SSL connection. (The former is simpler but won't do as well with NATs)</td></tr><tr id="0" style="display: none;" colspan="3"><td colspan="3"><h2>in order to support SSL over uTP, the utp_socket manager either
needs to be able to receive packets on multiple ports, or we need to
peek into the first few bytes the payload stream of a socket to determine
@ -235,7 +235,58 @@ when it doesn't have any of the file do the following</h2><h4>../src/web_peer_co
{
// we should not try this server again.
t-&gt;remove_web_seed(this);
</pre></td></tr><tr style="background: #fcc"><td>relevance&nbsp;3</td><td><a href="javascript:expand(4)">../include/libtorrent/kademlia/find_data.hpp:60</a></td><td>rename this class to get_peers, since that's what it does find_data is an unnecessarily generic name</td></tr><tr id="4" style="display: none;" colspan="3"><td colspan="3"><h2>rename this class to get_peers, since that's what it does
</pre></td></tr><tr style="background: #fcc"><td>relevance&nbsp;3</td><td><a href="javascript:expand(4)">../src/kademlia/node.cpp:328</a></td><td>if uTP is enabled, we should say "implied_port": 1</td></tr><tr id="4" style="display: none;" colspan="3"><td colspan="3"><h2>if uTP is enabled, we should say "implied_port": 1</h2><h4>../src/kademlia/node.cpp:328</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> , end(v.end()); i != end; ++i)
{
#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_LOG(node) &lt;&lt; " announce-distance: " &lt;&lt; (160 - distance_exp(ih, i-&gt;first.id));
#endif
void* ptr = node.m_rpc.allocate_observer();
if (ptr == 0) return;
observer_ptr o(new (ptr) announce_observer(algo, i-&gt;first.ep(), i-&gt;first.id));
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
o-&gt;m_in_constructor = false;
#endif
entry e;
e["y"] = "q";
e["q"] = "announce_peer";
entry&amp; a = e["a"];
a["info_hash"] = ih.to_string();
a["port"] = listen_port;
a["token"] = i-&gt;second;
a["seed"] = int(seed);
<div style="background: #ffff00" width="100%"> node.m_rpc.invoke(e, i-&gt;first.ep(), o);
</div> }
}
}
void node_impl::add_router_node(udp::endpoint router)
{
#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_LOG(node) &lt;&lt; "adding router node: " &lt;&lt; router;
#endif
m_table.add_router_node(router);
}
void node_impl::add_node(udp::endpoint node)
{
// ping the node, and if we get a reply, it
// will be added to the routing table
void* ptr = m_rpc.allocate_observer();
if (ptr == 0) return;
// create a dummy traversal_algorithm
// this is unfortunately necessary for the observer
// to free itself from the pool when it's being released
boost::intrusive_ptr&lt;traversal_algorithm&gt; algo(
new traversal_algorithm(*this, (node_id::min)()));
observer_ptr o(new (ptr) null_observer(algo, node, node_id(0)));
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
o-&gt;m_in_constructor = false;
#endif
entry e;
e["y"] = "q";
</pre></td></tr><tr style="background: #fcc"><td>relevance&nbsp;3</td><td><a href="javascript:expand(5)">../include/libtorrent/kademlia/find_data.hpp:60</a></td><td>rename this class to get_peers, since that's what it does find_data is an unnecessarily generic name</td></tr><tr id="5" style="display: none;" colspan="3"><td colspan="3"><h2>rename this class to get_peers, since that's what it does
find_data is an unnecessarily generic name</h2><h4>../include/libtorrent/kademlia/find_data.hpp:60</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">#include &lt;libtorrent/kademlia/node_id.hpp&gt;
#include &lt;libtorrent/kademlia/routing_table.hpp&gt;
#include &lt;libtorrent/kademlia/rpc_manager.hpp&gt;
@ -287,7 +338,7 @@ protected:
data_callback m_data_callback;
nodes_callback m_nodes_callback;
std::map&lt;node_id, std::string&gt; m_write_tokens;
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(5)">../src/torrent.cpp:8258</a></td><td>will pick_pieces ever return an empty set?</td></tr><tr id="5" style="display: none;" colspan="3"><td colspan="3"><h2>will pick_pieces ever return an empty set?</h2><h4>../src/torrent.cpp:8258</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> if (added_request)
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(6)">../src/torrent.cpp:8258</a></td><td>will pick_pieces ever return an empty set?</td></tr><tr id="6" style="display: none;" colspan="3"><td colspan="3"><h2>will pick_pieces ever return an empty set?</h2><h4>../src/torrent.cpp:8258</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> if (added_request)
{
peers_with_requests.insert(peers_with_requests.begin(), &amp;c);
if (i-&gt;first_requested == min_time()) i-&gt;first_requested = now;
@ -338,7 +389,7 @@ protected:
void torrent::remove_web_seed(std::string const&amp; url, web_seed_entry::type_t type)
{
std::list&lt;web_seed_entry&gt;::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end()
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(6)">../src/utp_stream.cpp:1862</a></td><td>we might want to do something else here as well, to resend the packet immediately without it being an MTU probe</td></tr><tr id="6" style="display: none;" colspan="3"><td colspan="3"><h2>we might want to do something else here
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(7)">../src/utp_stream.cpp:1862</a></td><td>we might want to do something else here as well, to resend the packet immediately without it being an MTU probe</td></tr><tr id="7" style="display: none;" colspan="3"><td colspan="3"><h2>we might want to do something else here
as well, to resend the packet immediately without
it being an MTU probe</h2><h4>../src/utp_stream.cpp:1862</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">// if ((rand() % 100) &gt; 0)
#endif
@ -391,7 +442,7 @@ it being an MTU probe</h2><h4>../src/utp_stream.cpp:1862</h4><pre style="backgro
m_state = UTP_STATE_ERROR_WAIT;
test_socket_state();
return false;
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(7)">../src/utp_stream.cpp:2505</a></td><td>sequence number, source IP and connection ID should be verified before accepting a reset packet</td></tr><tr id="7" style="display: none;" colspan="3"><td colspan="3"><h2>sequence number, source IP and connection ID should be
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(8)">../src/utp_stream.cpp:2505</a></td><td>sequence number, source IP and connection ID should be verified before accepting a reset packet</td></tr><tr id="8" style="display: none;" colspan="3"><td colspan="3"><h2>sequence number, source IP and connection ID should be
verified before accepting a reset packet</h2><h4>../src/utp_stream.cpp:2505</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> m_reply_micro = boost::uint32_t(total_microseconds(receive_time - min_time()))
- ph-&gt;timestamp_microseconds;
boost::uint32_t prev_base = m_their_delay_hist.initialized() ? m_their_delay_hist.base() : 0;
@ -443,7 +494,7 @@ verified before accepting a reset packet</h2><h4>../src/utp_stream.cpp:2505</h4>
, this, int(ph-&gt;ack_nr), m_seq_nr);
m_sm-&gt;inc_stats_counter(utp_socket_manager::redundant_pkts_in);
return true;
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(8)">../src/web_peer_connection.cpp:546</a></td><td>create a mapping of file-index to redirection URLs. Use that to form URLs instead. Support to reconnect to a new server without destructing this peer_connection</td></tr><tr id="8" style="display: none;" colspan="3"><td colspan="3"><h2>create a mapping of file-index to redirection URLs. Use that to form URLs instead. Support to reconnect to a new server without destructing this peer_connection</h2><h4>../src/web_peer_connection.cpp:546</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> t-&gt;remove_web_seed(this);
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(9)">../src/web_peer_connection.cpp:546</a></td><td>create a mapping of file-index to redirection URLs. Use that to form URLs instead. Support to reconnect to a new server without destructing this peer_connection</td></tr><tr id="9" style="display: none;" colspan="3"><td colspan="3"><h2>create a mapping of file-index to redirection URLs. Use that to form URLs instead. Support to reconnect to a new server without destructing this peer_connection</h2><h4>../src/web_peer_connection.cpp:546</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> t-&gt;remove_web_seed(this);
disconnect(errors::missing_location, 2);
#ifdef TORRENT_DEBUG
TORRENT_ASSERT(m_statistics.last_payload_downloaded()
@ -494,7 +545,7 @@ verified before accepting a reset packet</h2><h4>../src/utp_stream.cpp:2505</h4>
return;
}
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(9)">../src/kademlia/node.cpp:69</a></td><td>make this configurable in dht_settings</td></tr><tr id="9" style="display: none;" colspan="3"><td colspan="3"><h2>make this configurable in dht_settings</h2><h4>../src/kademlia/node.cpp:69</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">#include "libtorrent/kademlia/routing_table.hpp"
</pre></td></tr><tr style="background: #cfc"><td>relevance&nbsp;2</td><td><a href="javascript:expand(10)">../src/kademlia/node.cpp:69</a></td><td>make this configurable in dht_settings</td></tr><tr id="10" style="display: none;" colspan="3"><td colspan="3"><h2>make this configurable in dht_settings</h2><h4>../src/kademlia/node.cpp:69</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">#include "libtorrent/kademlia/routing_table.hpp"
#include "libtorrent/kademlia/node.hpp"
#include &lt;libtorrent/kademlia/dht_observer.hpp&gt;
@ -545,7 +596,7 @@ void purge_peers(std::set&lt;peer_entry&gt;&amp; peers)
void nop() {}
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(10)">../src/http_seed_connection.cpp:117</a></td><td>in chunked encoding mode, this assert won't hold. the chunk headers should be subtracted from the receive_buffer_size</td></tr><tr id="10" style="display: none;" colspan="3"><td colspan="3"><h2>in chunked encoding mode, this assert won't hold.
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(11)">../src/http_seed_connection.cpp:117</a></td><td>in chunked encoding mode, this assert won't hold. the chunk headers should be subtracted from the receive_buffer_size</td></tr><tr id="11" style="display: none;" colspan="3"><td colspan="3"><h2>in chunked encoding mode, this assert won't hold.
the chunk headers should be subtracted from the receive_buffer_size</h2><h4>../src/http_seed_connection.cpp:117</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> boost::optional&lt;piece_block_progress&gt;
http_seed_connection::downloading_piece_progress() const
{
@ -597,7 +648,7 @@ the chunk headers should be subtracted from the receive_buffer_size</h2><h4>../s
std::string request;
request.reserve(400);
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(11)">../src/peer_connection.cpp:2570</a></td><td>peers should really be corked/uncorked outside of all completed disk operations</td></tr><tr id="11" style="display: none;" colspan="3"><td colspan="3"><h2>peers should really be corked/uncorked outside of
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(12)">../src/peer_connection.cpp:2570</a></td><td>peers should really be corked/uncorked outside of all completed disk operations</td></tr><tr id="12" style="display: none;" colspan="3"><td colspan="3"><h2>peers should really be corked/uncorked outside of
all completed disk operations</h2><h4>../src/peer_connection.cpp:2570</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> }
if (is_disconnecting()) return;
@ -649,7 +700,7 @@ all completed disk operations</h2><h4>../src/peer_connection.cpp:2570</h4><pre s
return;
}
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(12)">../src/session_impl.cpp:5553</a></td><td>report the proper address of the router as the source IP of this understanding of our external address, instead of the empty address</td></tr><tr id="12" style="display: none;" colspan="3"><td colspan="3"><h2>report the proper address of the router as the source IP of
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(13)">../src/session_impl.cpp:5553</a></td><td>report the proper address of the router as the source IP of this understanding of our external address, instead of the empty address</td></tr><tr id="13" style="display: none;" colspan="3"><td colspan="3"><h2>report the proper address of the router as the source IP of
this understanding of our external address, instead of the empty address</h2><h4>../src/session_impl.cpp:5553</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> void session_impl::on_port_mapping(int mapping, address const&amp; ip, int port
, error_code const&amp; ec, int map_transport)
{
@ -701,7 +752,7 @@ this understanding of our external address, instead of the empty address</h2><h4
{
// INVARIANT_CHECK;
TORRENT_ASSERT(is_network_thread());
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(13)">../src/session_impl.cpp:5763</a></td><td>report errors as alerts</td></tr><tr id="13" style="display: none;" colspan="3"><td colspan="3"><h2>report errors as alerts</h2><h4>../src/session_impl.cpp:5763</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> }
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(14)">../src/session_impl.cpp:5763</a></td><td>report errors as alerts</td></tr><tr id="14" style="display: none;" colspan="3"><td colspan="3"><h2>report errors as alerts</h2><h4>../src/session_impl.cpp:5763</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> }
void session_impl::add_dht_router(std::pair&lt;std::string, int&gt; const&amp; node)
{
@ -752,7 +803,7 @@ this understanding of our external address, instead of the empty address</h2><h4
, local_port, external_port);
return;
}
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(14)">../src/session_impl.cpp:6234</a></td><td>we only need to do this if our global IPv4 address has changed since the DHT (currently) only supports IPv4. Since restarting the DHT is kind of expensive, it would be nice to not do it unnecessarily</td></tr><tr id="14" style="display: none;" colspan="3"><td colspan="3"><h2>we only need to do this if our global IPv4 address has changed
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(15)">../src/session_impl.cpp:6234</a></td><td>we only need to do this if our global IPv4 address has changed since the DHT (currently) only supports IPv4. Since restarting the DHT is kind of expensive, it would be nice to not do it unnecessarily</td></tr><tr id="15" style="display: none;" colspan="3"><td colspan="3"><h2>we only need to do this if our global IPv4 address has changed
since the DHT (currently) only supports IPv4. Since restarting the DHT
is kind of expensive, it would be nice to not do it unnecessarily</h2><h4>../src/session_impl.cpp:6234</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> void session_impl::set_external_address(address const&amp; ip
, int source_type, address const&amp; source)
@ -805,7 +856,7 @@ is kind of expensive, it would be nice to not do it unnecessarily</h2><h4>../src
#ifdef TORRENT_DISK_STATS
TORRENT_ASSERT(m_buffer_allocations &gt;= 0);
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(15)">../src/torrent.cpp:1043</a></td><td>make this depend on the error and on the filesystem the files are being downloaded to. If the error is no_space_left_on_device and the filesystem doesn't support sparse files, only zero the priorities of the pieces that are at the tails of all files, leaving everything up to the highest written piece in each file</td></tr><tr id="15" style="display: none;" colspan="3"><td colspan="3"><h2>make this depend on the error and on the filesystem the
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(16)">../src/torrent.cpp:1043</a></td><td>make this depend on the error and on the filesystem the files are being downloaded to. If the error is no_space_left_on_device and the filesystem doesn't support sparse files, only zero the priorities of the pieces that are at the tails of all files, leaving everything up to the highest written piece in each file</td></tr><tr id="16" style="display: none;" colspan="3"><td colspan="3"><h2>make this depend on the error and on the filesystem the
files are being downloaded to. If the error is no_space_left_on_device
and the filesystem doesn't support sparse files, only zero the priorities
of the pieces that are at the tails of all files, leaving everything
@ -860,7 +911,7 @@ up to the highest written piece in each file</h2><h4>../src/torrent.cpp:1043</h4
{
int size = m_torrent_file-&gt;piece_size(r.piece);
if (rp-&gt;fail)
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(16)">../src/torrent.cpp:5330</a></td><td>save the send_stats state instead of throwing them away it may pose an issue when downgrading though</td></tr><tr id="16" style="display: none;" colspan="3"><td colspan="3"><h2>save the send_stats state instead of throwing them away
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(17)">../src/torrent.cpp:5330</a></td><td>save the send_stats state instead of throwing them away it may pose an issue when downgrading though</td></tr><tr id="17" style="display: none;" colspan="3"><td colspan="3"><h2>save the send_stats state instead of throwing them away
it may pose an issue when downgrading though</h2><h4>../src/torrent.cpp:5330</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> ? (1 &lt;&lt; k) : 0;
bitmask.append(1, v);
TORRENT_ASSERT(bits == 8 || j == num_bitmask_bytes - 1);
@ -912,7 +963,7 @@ it may pose an issue when downgrading though</h2><h4>../src/torrent.cpp:5330</h4
// write have bitmask
// the pieces string has one byte per piece. Each
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(17)">../src/torrent.cpp:6236</a></td><td>should disconnect all peers that have the pieces we have not just seeds. It would be pretty expensive to check all pieces for all peers though</td></tr><tr id="17" style="display: none;" colspan="3"><td colspan="3"><h2>should disconnect all peers that have the pieces we have
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(18)">../src/torrent.cpp:6236</a></td><td>should disconnect all peers that have the pieces we have not just seeds. It would be pretty expensive to check all pieces for all peers though</td></tr><tr id="18" style="display: none;" colspan="3"><td colspan="3"><h2>should disconnect all peers that have the pieces we have
not just seeds. It would be pretty expensive to check all pieces
for all peers though</h2><h4>../src/torrent.cpp:6236</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> TORRENT_ASSERT(m_state != torrent_status::finished &amp;&amp; m_state != torrent_status::seeding);
@ -965,7 +1016,7 @@ for all peers though</h2><h4>../src/torrent.cpp:6236</h4><pre style="background:
// under a different limit with the auto-manager. Make sure we
// update auto-manage torrents in that case
if (m_auto_managed)
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(18)">../src/torrent_info.cpp:181</a></td><td>we might save constructing a std::string if this would take a char const* instead</td></tr><tr id="18" style="display: none;" colspan="3"><td colspan="3"><h2>we might save constructing a std::string if this would take a char const* instead</h2><h4>../src/torrent_info.cpp:181</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(19)">../src/torrent_info.cpp:181</a></td><td>we might save constructing a std::string if this would take a char const* instead</td></tr><tr id="19" style="display: none;" colspan="3"><td colspan="3"><h2>we might save constructing a std::string if this would take a char const* instead</h2><h4>../src/torrent_info.cpp:181</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
tmp_path += i[0];
tmp_path += i[1];
tmp_path += i[2];
@ -1016,7 +1067,7 @@ for all peers though</h2><h4>../src/torrent.cpp:6236</h4><pre style="background:
path_element.resize(max_path_len);
}
else
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(19)">../src/torrent_info.cpp:401</a></td><td>this logic should be a separate step done once the torrent is loaded, and the original filenames should be preserved!</td></tr><tr id="19" style="display: none;" colspan="3"><td colspan="3"><h2>this logic should be a separate step
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(20)">../src/torrent_info.cpp:401</a></td><td>this logic should be a separate step done once the torrent is loaded, and the original filenames should be preserved!</td></tr><tr id="20" style="display: none;" colspan="3"><td colspan="3"><h2>this logic should be a separate step
done once the torrent is loaded, and the original
filenames should be preserved!</h2><h4>../src/torrent_info.cpp:401</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
while (*s1 != 0 || *s2 != 0)
@ -1069,7 +1120,7 @@ filenames should be preserved!</h2><h4>../src/torrent_info.cpp:401</h4><pre styl
// This is a memory optimization! Instead of having
// each entry keep a string for its filename, make it
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(20)">../src/torrent_info.cpp:437</a></td><td>once the filename renaming is removed from here this check can be removed as well</td></tr><tr id="20" style="display: none;" colspan="3"><td colspan="3"><h2>once the filename renaming is removed from here
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(21)">../src/torrent_info.cpp:437</a></td><td>once the filename renaming is removed from here this check can be removed as well</td></tr><tr id="21" style="display: none;" colspan="3"><td colspan="3"><h2>once the filename renaming is removed from here
this check can be removed as well</h2><h4>../src/torrent_info.cpp:437</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // increase the counter
int cnt = 0;
if (!files.insert(e.path).second)
@ -1121,7 +1172,7 @@ this check can be removed as well</h2><h4>../src/torrent_info.cpp:437</h4><pre s
{
TORRENT_ASSERT(leafs &gt; 0);
return (leafs &lt;&lt; 1) - 1;
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(21)">../src/kademlia/node.cpp:772</a></td><td>find_node should write directly to the response entry</td></tr><tr id="21" style="display: none;" colspan="3"><td colspan="3"><h2>find_node should write directly to the response entry</h2><h4>../src/kademlia/node.cpp:772</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(22)">../src/kademlia/node.cpp:782</a></td><td>find_node should write directly to the response entry</td></tr><tr id="22" style="display: none;" colspan="3"><td colspan="3"><h2>find_node should write directly to the response entry</h2><h4>../src/kademlia/node.cpp:782</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
TORRENT_LOG(node) &lt;&lt; " values: " &lt;&lt; reply["values"].list().size();
}
#endif
@ -1172,7 +1223,7 @@ this check can be removed as well</h2><h4>../src/torrent_info.cpp:437</h4><pre s
// listen port and instead use the source port of the packet?
if (msg_keys[5] &amp;&amp; msg_keys[5]-&gt;int_value() != 0)
port = m.addr.port();
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(22)">../include/libtorrent/ip_voter.hpp:100</a></td><td>instead, have one instance per possible subnet, global IPv4, global IPv6, loopback, 192.168.x.x, 10.x.x.x, etc.</td></tr><tr id="22" style="display: none;" colspan="3"><td colspan="3"><h2>instead, have one instance per possible subnet, global IPv4, global IPv6, loopback, 192.168.x.x, 10.x.x.x, etc.</h2><h4>../include/libtorrent/ip_voter.hpp:100</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> bloom_filter&lt;32&gt; m_external_address_voters;
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(23)">../include/libtorrent/ip_voter.hpp:100</a></td><td>instead, have one instance per possible subnet, global IPv4, global IPv6, loopback, 192.168.x.x, 10.x.x.x, etc.</td></tr><tr id="23" style="display: none;" colspan="3"><td colspan="3"><h2>instead, have one instance per possible subnet, global IPv4, global IPv6, loopback, 192.168.x.x, 10.x.x.x, etc.</h2><h4>../include/libtorrent/ip_voter.hpp:100</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> bloom_filter&lt;32&gt; m_external_address_voters;
std::vector&lt;external_ip_t&gt; m_external_addresses;
address m_external_address;
};
@ -1199,7 +1250,7 @@ this check can be removed as well</h2><h4>../src/torrent_info.cpp:437</h4><pre s
#endif
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(23)">../include/libtorrent/utp_stream.hpp:378</a></td><td>implement blocking write. Low priority since it's not used (yet)</td></tr><tr id="23" style="display: none;" colspan="3"><td colspan="3"><h2>implement blocking write. Low priority since it's not used (yet)</h2><h4>../include/libtorrent/utp_stream.hpp:378</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> for (typename Mutable_Buffers::const_iterator i = buffers.begin()
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(24)">../include/libtorrent/utp_stream.hpp:378</a></td><td>implement blocking write. Low priority since it's not used (yet)</td></tr><tr id="24" style="display: none;" colspan="3"><td colspan="3"><h2>implement blocking write. Low priority since it's not used (yet)</h2><h4>../include/libtorrent/utp_stream.hpp:378</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> for (typename Mutable_Buffers::const_iterator i = buffers.begin()
, end(buffers.end()); i != end; ++i)
{
using asio::buffer_cast;
@ -1250,7 +1301,7 @@ this check can be removed as well</h2><h4>../src/torrent_info.cpp:437</h4><pre s
TORRENT_ASSERT(false);
}
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(24)">../include/libtorrent/web_peer_connection.hpp:126</a></td><td>if we make this be a disk_buffer_holder instead we would save a copy sometimes use allocate_disk_receive_buffer and release_disk_receive_buffer</td></tr><tr id="24" style="display: none;" colspan="3"><td colspan="3"><h2>if we make this be a disk_buffer_holder instead
</pre></td></tr><tr style="background: #ccf"><td>relevance&nbsp;1</td><td><a href="javascript:expand(25)">../include/libtorrent/web_peer_connection.hpp:126</a></td><td>if we make this be a disk_buffer_holder instead we would save a copy sometimes use allocate_disk_receive_buffer and release_disk_receive_buffer</td></tr><tr id="25" style="display: none;" colspan="3"><td colspan="3"><h2>if we make this be a disk_buffer_holder instead
we would save a copy sometimes
use allocate_disk_receive_buffer and release_disk_receive_buffer</h2><h4>../include/libtorrent/web_peer_connection.hpp:126</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
bool maybe_harvest_block();
@ -1303,7 +1354,7 @@ use allocate_disk_receive_buffer and release_disk_receive_buffer</h2><h4>../incl
};
}
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(25)">../src/bt_peer_connection.cpp:615</a></td><td>this could be optimized using knuth morris pratt</td></tr><tr id="25" style="display: none;" colspan="3"><td colspan="3"><h2>this could be optimized using knuth morris pratt</h2><h4>../src/bt_peer_connection.cpp:615</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(26)">../src/bt_peer_connection.cpp:621</a></td><td>this could be optimized using knuth morris pratt</td></tr><tr id="26" style="display: none;" colspan="3"><td colspan="3"><h2>this could be optimized using knuth morris pratt</h2><h4>../src/bt_peer_connection.cpp:621</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
disconnect(errors::no_memory);
return;
}
@ -1354,7 +1405,7 @@ use allocate_disk_receive_buffer and release_disk_receive_buffer</h2><h4>../incl
// }
// no complete sync
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(26)">../src/bt_peer_connection.cpp:2081</a></td><td>if we're finished, send upload_only message</td></tr><tr id="26" style="display: none;" colspan="3"><td colspan="3"><h2>if we're finished, send upload_only message</h2><h4>../src/bt_peer_connection.cpp:2081</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> if (msg[5 + k / 8] &amp; (0x80 &gt;&gt; (k % 8))) bitfield_string[k] = '1';
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(27)">../src/bt_peer_connection.cpp:2085</a></td><td>if we're finished, send upload_only message</td></tr><tr id="27" style="display: none;" colspan="3"><td colspan="3"><h2>if we're finished, send upload_only message</h2><h4>../src/bt_peer_connection.cpp:2085</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> if (msg[5 + k / 8] &amp; (0x80 &gt;&gt; (k % 8))) bitfield_string[k] = '1';
else bitfield_string[k] = '0';
}
peer_log("==&gt; BITFIELD [ %s ]", bitfield_string.c_str());
@ -1405,8 +1456,8 @@ use allocate_disk_receive_buffer and release_disk_receive_buffer</h2><h4>../incl
std::back_insert_iterator&lt;std::string&gt; out(remote_address);
detail::write_address(remote().address(), out);
handshake["yourip"] = remote_address;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(27)">../src/bt_peer_connection.cpp:3323</a></td><td>move the erasing into the loop above remove all payload ranges that has been sent</td></tr><tr id="27" style="display: none;" colspan="3"><td colspan="3"><h2>move the erasing into the loop above
remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.cpp:3323</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> for (std::vector&lt;range&gt;::iterator i = m_payloads.begin();
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(28)">../src/bt_peer_connection.cpp:3325</a></td><td>move the erasing into the loop above remove all payload ranges that has been sent</td></tr><tr id="28" style="display: none;" colspan="3"><td colspan="3"><h2>move the erasing into the loop above
remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.cpp:3325</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> for (std::vector&lt;range&gt;::iterator i = m_payloads.begin();
i != m_payloads.end(); ++i)
{
i-&gt;start -= bytes_transferred;
@ -1457,7 +1508,7 @@ remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.c
TORRENT_ASSERT(m_sent_handshake);
}
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(28)">../src/file.cpp:1370</a></td><td>is there any way to pre-fetch data from a file on windows?</td></tr><tr id="28" style="display: none;" colspan="3"><td colspan="3"><h2>is there any way to pre-fetch data from a file on windows?</h2><h4>../src/file.cpp:1370</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(29)">../src/file.cpp:1370</a></td><td>is there any way to pre-fetch data from a file on windows?</td></tr><tr id="29" style="display: none;" colspan="3"><td colspan="3"><h2>is there any way to pre-fetch data from a file on windows?</h2><h4>../src/file.cpp:1370</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
void file::init_file()
{
if (m_page_size != 0) return;
@ -1508,7 +1559,7 @@ remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.c
#ifdef TORRENT_DEBUG
if (m_open_mode &amp; no_buffer)
{
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(29)">../src/http_tracker_connection.cpp:99</a></td><td>support authentication (i.e. user name and password) in the URL</td></tr><tr id="29" style="display: none;" colspan="3"><td colspan="3"><h2>support authentication (i.e. user name and password) in the URL</h2><h4>../src/http_tracker_connection.cpp:99</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> , aux::session_impl const&amp; ses
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(30)">../src/http_tracker_connection.cpp:99</a></td><td>support authentication (i.e. user name and password) in the URL</td></tr><tr id="30" style="display: none;" colspan="3"><td colspan="3"><h2>support authentication (i.e. user name and password) in the URL</h2><h4>../src/http_tracker_connection.cpp:99</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> , aux::session_impl const&amp; ses
, proxy_settings const&amp; ps
, std::string const&amp; auth
#if TORRENT_USE_I2P
@ -1559,7 +1610,7 @@ remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.c
if (arguments_start != std::string::npos)
url += "&amp;";
else
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(30)">../src/i2p_stream.cpp:204</a></td><td>move this to proxy_base and use it in all proxies</td></tr><tr id="30" style="display: none;" colspan="3"><td colspan="3"><h2>move this to proxy_base and use it in all proxies</h2><h4>../src/i2p_stream.cpp:204</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(31)">../src/i2p_stream.cpp:204</a></td><td>move this to proxy_base and use it in all proxies</td></tr><tr id="31" style="display: none;" colspan="3"><td colspan="3"><h2>move this to proxy_base and use it in all proxies</h2><h4>../src/i2p_stream.cpp:204</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
i2p_stream::i2p_stream(io_service&amp; io_service)
: proxy_base(io_service)
, m_id(0)
@ -1610,7 +1661,7 @@ remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.c
void i2p_stream::connected(error_code const&amp; e, boost::shared_ptr&lt;handler_type&gt; h)
{
TORRENT_ASSERT(m_magic == 0x1337);
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(31)">../src/packet_buffer.cpp:176</a></td><td>use compare_less_wrap for this comparison as well</td></tr><tr id="31" style="display: none;" colspan="3"><td colspan="3"><h2>use compare_less_wrap for this comparison as well</h2><h4>../src/packet_buffer.cpp:176</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> while (new_size &lt; size)
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(32)">../src/packet_buffer.cpp:176</a></td><td>use compare_less_wrap for this comparison as well</td></tr><tr id="32" style="display: none;" colspan="3"><td colspan="3"><h2>use compare_less_wrap for this comparison as well</h2><h4>../src/packet_buffer.cpp:176</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> while (new_size &lt; size)
new_size &lt;&lt;= 1;
void** new_storage = (void**)malloc(sizeof(void*) * new_size);
@ -1661,7 +1712,7 @@ remove all payload ranges that has been sent</h2><h4>../src/bt_peer_connection.c
if (m_storage[m_last &amp; mask]) break;
++m_last;
m_last &amp;= 0xffff;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(32)">../src/peer_connection.cpp:2733</a></td><td>this might need something more so that once we have the metadata we can construct a full bitfield</td></tr><tr id="32" style="display: none;" colspan="3"><td colspan="3"><h2>this might need something more
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(33)">../src/peer_connection.cpp:2733</a></td><td>this might need something more so that once we have the metadata we can construct a full bitfield</td></tr><tr id="33" style="display: none;" colspan="3"><td colspan="3"><h2>this might need something more
so that once we have the metadata
we can construct a full bitfield</h2><h4>../src/peer_connection.cpp:2733</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
#ifdef TORRENT_VERBOSE_LOGGING
@ -1714,7 +1765,7 @@ we can construct a full bitfield</h2><h4>../src/peer_connection.cpp:2733</h4><pr
boost::shared_ptr&lt;torrent&gt; t = m_torrent.lock();
TORRENT_ASSERT(t);
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(33)">../src/peer_connection.cpp:2864</a></td><td>sort the allowed fast set in priority order</td></tr><tr id="33" style="display: none;" colspan="3"><td colspan="3"><h2>sort the allowed fast set in priority order</h2><h4>../src/peer_connection.cpp:2864</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // this piece index later
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(34)">../src/peer_connection.cpp:2864</a></td><td>sort the allowed fast set in priority order</td></tr><tr id="34" style="display: none;" colspan="3"><td colspan="3"><h2>sort the allowed fast set in priority order</h2><h4>../src/peer_connection.cpp:2864</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // this piece index later
m_allowed_fast.push_back(index);
// if the peer has the piece and we want
@ -1765,7 +1816,7 @@ we can construct a full bitfield</h2><h4>../src/peer_connection.cpp:2733</h4><pr
TORRENT_ASSERT(t-&gt;has_picker());
TORRENT_ASSERT(t-&gt;picker().is_requested(block));
#endif
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(34)">../src/peer_connection.cpp:4584</a></td><td>peers should really be corked/uncorked outside of all completed disk operations</td></tr><tr id="34" style="display: none;" colspan="3"><td colspan="3"><h2>peers should really be corked/uncorked outside of
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(35)">../src/peer_connection.cpp:4584</a></td><td>peers should really be corked/uncorked outside of all completed disk operations</td></tr><tr id="35" style="display: none;" colspan="3"><td colspan="3"><h2>peers should really be corked/uncorked outside of
all completed disk operations</h2><h4>../src/peer_connection.cpp:4584</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // this means we're in seed mode and we haven't yet
// verified this piece (r.piece)
t-&gt;filesystem().async_read_and_hash(r, boost::bind(&amp;peer_connection::on_disk_read_complete
@ -1817,7 +1868,7 @@ all completed disk operations</h2><h4>../src/peer_connection.cpp:4584</h4><pre s
#endif
write_reject_request(r);
if (t-&gt;seed_mode()) t-&gt;leave_seed_mode(false);
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(35)">../src/policy.cpp:857</a></td><td>only allow _one_ connection to use this override at a time</td></tr><tr id="35" style="display: none;" colspan="3"><td colspan="3"><h2>only allow _one_ connection to use this
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(36)">../src/policy.cpp:857</a></td><td>only allow _one_ connection to use this override at a time</td></tr><tr id="36" style="display: none;" colspan="3"><td colspan="3"><h2>only allow _one_ connection to use this
override at a time</h2><h4>../src/policy.cpp:857</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> " external: " &lt;&lt; external.external_address(m_peers[candidate]-&gt;address()) &lt;&lt;
" t: " &lt;&lt; (session_time - m_peers[candidate]-&gt;last_connected) &lt;&lt;
" ]\n";
@ -1869,7 +1920,7 @@ override at a time</h2><h4>../src/policy.cpp:857</h4><pre style="background: #f6
{
iter = std::lower_bound(
m_peers.begin(), m_peers.end()
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(36)">../src/policy.cpp:1902</a></td><td>how do we deal with our external address changing? Pass in a force-update maybe? and keep a version number in policy</td></tr><tr id="36" style="display: none;" colspan="3"><td colspan="3"><h2>how do we deal with our external address changing? Pass in a force-update maybe? and keep a version number in policy</h2><h4>../src/policy.cpp:1902</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">#endif
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(37)">../src/policy.cpp:1902</a></td><td>how do we deal with our external address changing? Pass in a force-update maybe? and keep a version number in policy</td></tr><tr id="37" style="display: none;" colspan="3"><td colspan="3"><h2>how do we deal with our external address changing? Pass in a force-update maybe? and keep a version number in policy</h2><h4>../src/policy.cpp:1902</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">#endif
, on_parole(false)
, banned(false)
#ifndef TORRENT_DISABLE_DHT
@ -1920,7 +1971,7 @@ override at a time</h2><h4>../src/policy.cpp:857</h4><pre style="background: #f6
{
return size_type(prev_amount_upload) &lt;&lt; 10;
}
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(37)">../src/session_impl.cpp:1764</a></td><td>recalculate all connect candidates for all torrents</td></tr><tr id="37" style="display: none;" colspan="3"><td colspan="3"><h2>recalculate all connect candidates for all torrents</h2><h4>../src/session_impl.cpp:1764</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // #error closing the udp socket here means that
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(38)">../src/session_impl.cpp:1764</a></td><td>recalculate all connect candidates for all torrents</td></tr><tr id="38" style="display: none;" colspan="3"><td colspan="3"><h2>recalculate all connect candidates for all torrents</h2><h4>../src/session_impl.cpp:1764</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // #error closing the udp socket here means that
// the uTP connections cannot be closed gracefully
m_udp_socket.close();
m_external_udp_port = 0;
@ -1971,7 +2022,7 @@ override at a time</h2><h4>../src/policy.cpp:857</h4><pre style="background: #f6
template &lt;class Socket&gt;
void static set_socket_buffer_size(Socket&amp; s, session_settings const&amp; sett, error_code&amp; ec)
{
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(38)">../src/session_impl.cpp:3227</a></td><td>have a separate list for these connections, instead of having to loop through all of them</td></tr><tr id="38" style="display: none;" colspan="3"><td colspan="3"><h2>have a separate list for these connections, instead of having to loop through all of them</h2><h4>../src/session_impl.cpp:3227</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // --------------------------------------------------------------
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(39)">../src/session_impl.cpp:3227</a></td><td>have a separate list for these connections, instead of having to loop through all of them</td></tr><tr id="39" style="display: none;" colspan="3"><td colspan="3"><h2>have a separate list for these connections, instead of having to loop through all of them</h2><h4>../src/session_impl.cpp:3227</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // --------------------------------------------------------------
if (!m_paused) m_auto_manage_time_scaler--;
if (m_auto_manage_time_scaler &lt; 0)
{
@ -2022,7 +2073,7 @@ override at a time</h2><h4>../src/policy.cpp:857</h4><pre style="background: #f6
TORRENT_ASSERT(!t.is_aborted());
if (t.statistics().upload_rate() * 11 / 10 &gt; t.upload_limit())
++congested_torrents;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(39)">../src/session_impl.cpp:4317</a></td><td>allow extensions to sort torrents for queuing</td></tr><tr id="39" style="display: none;" colspan="3"><td colspan="3"><h2>allow extensions to sort torrents for queuing</h2><h4>../src/session_impl.cpp:4317</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> else if (!t-&gt;is_paused())
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(40)">../src/session_impl.cpp:4317</a></td><td>allow extensions to sort torrents for queuing</td></tr><tr id="40" style="display: none;" colspan="3"><td colspan="3"><h2>allow extensions to sort torrents for queuing</h2><h4>../src/session_impl.cpp:4317</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> else if (!t-&gt;is_paused())
{
TORRENT_ASSERT(t-&gt;m_resume_data_loaded || !t-&gt;valid_metadata());
--hard_limit;
@ -2073,7 +2124,7 @@ override at a time</h2><h4>../src/policy.cpp:857</h4><pre style="background: #f6
void session_impl::recalculate_optimistic_unchoke_slots()
{
TORRENT_ASSERT(is_network_thread());
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(40)">../src/session_impl.cpp:4473</a></td><td>use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming connections</td></tr><tr id="40" style="display: none;" colspan="3"><td colspan="3"><h2>use a lower limit than m_settings.connections_limit
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(41)">../src/session_impl.cpp:4473</a></td><td>use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming connections</td></tr><tr id="41" style="display: none;" colspan="3"><td colspan="3"><h2>use a lower limit than m_settings.connections_limit
to allocate the to 10% or so of connection slots for incoming
connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
if (m_boost_connections &gt; max_connections)
@ -2126,7 +2177,7 @@ connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6
int num_attempts = 1;
if (!t.is_finished())
{
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(41)">../src/session_impl.cpp:4507</a></td><td>make this bias configurable</td></tr><tr id="41" style="display: none;" colspan="3"><td colspan="3"><h2>make this bias configurable</h2><h4>../src/session_impl.cpp:4507</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"></pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(42)">../src/session_impl.cpp:4508</a></td><td>also take average_peers into account, to create a bias for downloading torrents with < average peers</td></tr><tr id="42" style="display: none;" colspan="3"><td colspan="3"><h2>also take average_peers into account, to create a bias for downloading torrents with < average peers</h2><h4>../src/session_impl.cpp:4508</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> average_peers = num_downloads_peers / num_downloads;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(42)">../src/session_impl.cpp:4507</a></td><td>make this bias configurable</td></tr><tr id="42" style="display: none;" colspan="3"><td colspan="3"><h2>make this bias configurable</h2><h4>../src/session_impl.cpp:4507</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"></pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(43)">../src/session_impl.cpp:4508</a></td><td>also take average_peers into account, to create a bias for downloading torrents with < average peers</td></tr><tr id="43" style="display: none;" colspan="3"><td colspan="3"><h2>also take average_peers into account, to create a bias for downloading torrents with < average peers</h2><h4>../src/session_impl.cpp:4508</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> average_peers = num_downloads_peers / num_downloads;
if (m_next_connect_torrent == m_torrents.end())
m_next_connect_torrent = m_torrents.begin();
@ -2177,7 +2228,7 @@ connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6
if (max_connections == 0) return;
if (num_connections() &gt;= m_settings.connections_limit) return;
}
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(43)">../src/session_impl.cpp:4652</a></td><td>make configurable</td></tr><tr id="43" style="display: none;" colspan="3"><td colspan="3"><h2>make configurable</h2><h4>../src/session_impl.cpp:4652</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(44)">../src/session_impl.cpp:4652</a></td><td>make configurable</td></tr><tr id="44" style="display: none;" colspan="3"><td colspan="3"><h2>make configurable</h2><h4>../src/session_impl.cpp:4652</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
#ifdef TORRENT_DEBUG
for (std::vector&lt;peer_connection*&gt;::const_iterator i = peers.begin()
, end(peers.end()), prev(peers.end()); i != end; ++i)
@ -2210,7 +2261,7 @@ connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6
++m_allowed_upload_slots;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(44)">../src/session_impl.cpp:4666</a></td><td>make configurable</td></tr><tr id="44" style="display: none;" colspan="3"><td colspan="3"><h2>make configurable</h2><h4>../src/session_impl.cpp:4666</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> &gt;= (*i)-&gt;uploaded_in_last_round() * 1000
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(45)">../src/session_impl.cpp:4666</a></td><td>make configurable</td></tr><tr id="45" style="display: none;" colspan="3"><td colspan="3"><h2>make configurable</h2><h4>../src/session_impl.cpp:4666</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> &gt;= (*i)-&gt;uploaded_in_last_round() * 1000
* (1 + t2-&gt;priority()) / total_milliseconds(unchoke_interval));
}
prev = i;
@ -2261,7 +2312,7 @@ connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6
// if our current upload rate is less than 90% of our
// limit AND most torrents are not "congested", i.e.
// they are not holding back because of a per-torrent
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(45)">../src/storage.cpp:324</a></td><td>if the read fails, set error and exit immediately</td></tr><tr id="45" style="display: none;" colspan="3"><td colspan="3"><h2>if the read fails, set error and exit immediately</h2><h4>../src/storage.cpp:324</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> if (m_storage-&gt;disk_pool()) block_size = m_storage-&gt;disk_pool()-&gt;block_size();
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(46)">../src/storage.cpp:324</a></td><td>if the read fails, set error and exit immediately</td></tr><tr id="46" style="display: none;" colspan="3"><td colspan="3"><h2>if the read fails, set error and exit immediately</h2><h4>../src/storage.cpp:324</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> if (m_storage-&gt;disk_pool()) block_size = m_storage-&gt;disk_pool()-&gt;block_size();
int size = slot_size;
int num_blocks = (size + block_size - 1) / block_size;
@ -2312,7 +2363,7 @@ connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6
{
buf.iov_len = (std::min)(block_size, size);
// deliberately pass in 0 as flags, to disable random_access
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(46)">../src/storage.cpp:358</a></td><td>if the read fails, set error and exit immediately</td></tr><tr id="46" style="display: none;" colspan="3"><td colspan="3"><h2>if the read fails, set error and exit immediately</h2><h4>../src/storage.cpp:358</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(47)">../src/storage.cpp:358</a></td><td>if the read fails, set error and exit immediately</td></tr><tr id="47" style="display: none;" colspan="3"><td colspan="3"><h2>if the read fails, set error and exit immediately</h2><h4>../src/storage.cpp:358</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> {
ph.h.update((char const*)bufs[i].iov_base, bufs[i].iov_len);
small_piece_size -= bufs[i].iov_len;
}
@ -2363,7 +2414,7 @@ connections</h2><h4>../src/session_impl.cpp:4473</h4><pre style="background: #f6
, m_file_priority(file_prio)
, m_pool(fp)
, m_page_size(page_size())
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(47)">../src/storage.cpp:629</a></td><td>make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info</td></tr><tr id="47" style="display: none;" colspan="3"><td colspan="3"><h2>make this more generic to not just work if files have been
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(48)">../src/storage.cpp:629</a></td><td>make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info</td></tr><tr id="48" style="display: none;" colspan="3"><td colspan="3"><h2>make this more generic to not just work if files have been
renamed, but also if they have been merged into a single file for instance
maybe use the same format as .torrent files and reuse some code from torrent_info</h2><h4>../src/storage.cpp:629</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> for (;;)
{
@ -2416,7 +2467,7 @@ maybe use the same format as .torrent files and reuse some code from torrent_inf
for (int i = 0; i &lt; file_sizes_ent-&gt;list_size(); ++i)
{
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(48)">../src/storage.cpp:1246</a></td><td>what if file_base is used to merge several virtual files into a single physical file? We should probably disable this if file_base is used. This is not a widely used feature though</td></tr><tr id="48" style="display: none;" colspan="3"><td colspan="3"><h2>what if file_base is used to merge several virtual files
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(49)">../src/storage.cpp:1246</a></td><td>what if file_base is used to merge several virtual files into a single physical file? We should probably disable this if file_base is used. This is not a widely used feature though</td></tr><tr id="49" style="display: none;" colspan="3"><td colspan="3"><h2>what if file_base is used to merge several virtual files
into a single physical file? We should probably disable this
if file_base is used. This is not a widely used feature though</h2><h4>../src/storage.cpp:1246</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> int bytes_transferred = 0;
// if the file is opened in no_buffer mode, and the
@ -2469,7 +2520,7 @@ if file_base is used. This is not a widely used feature though</h2><h4>../src/st
// makes unaligned requests (and the disk cache is disabled or fully utilized
// for write cache).
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(49)">../src/torrent.cpp:1245</a></td><td>is verify_peer_cert called once per certificate in the chain, and this function just tells us which depth we're at right now? If so, the comment makes sense. any certificate that isn't the leaf (i.e. the one presented by the peer) should be accepted automatically, given preverified is true. The leaf certificate need to be verified to make sure its DN matches the info-hash</td></tr><tr id="49" style="display: none;" colspan="3"><td colspan="3"><h2>is verify_peer_cert called once per certificate in the chain, and
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(50)">../src/torrent.cpp:1245</a></td><td>is verify_peer_cert called once per certificate in the chain, and this function just tells us which depth we're at right now? If so, the comment makes sense. any certificate that isn't the leaf (i.e. the one presented by the peer) should be accepted automatically, given preverified is true. The leaf certificate need to be verified to make sure its DN matches the info-hash</td></tr><tr id="50" style="display: none;" colspan="3"><td colspan="3"><h2>is verify_peer_cert called once per certificate in the chain, and
this function just tells us which depth we're at right now? If so, the comment
makes sense.
any certificate that isn't the leaf (i.e. the one presented by the peer)
@ -2525,7 +2576,7 @@ need to be verified to make sure its DN matches the info-hash</h2><h4>../src/tor
{
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
match = true;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(50)">../src/torrent.cpp:5063</a></td><td>make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info The mapped_files needs to be read both in the network thread and in the disk thread, since they both have their own mapped files structures which are kept in sync</td></tr><tr id="50" style="display: none;" colspan="3"><td colspan="3"><h2>make this more generic to not just work if files have been
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(51)">../src/torrent.cpp:5063</a></td><td>make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info The mapped_files needs to be read both in the network thread and in the disk thread, since they both have their own mapped files structures which are kept in sync</td></tr><tr id="51" style="display: none;" colspan="3"><td colspan="3"><h2>make this more generic to not just work if files have been
renamed, but also if they have been merged into a single file for instance
maybe use the same format as .torrent files and reuse some code from torrent_info
The mapped_files needs to be read both in the network thread
@ -2581,7 +2632,7 @@ which are kept in sync</h2><h4>../src/torrent.cpp:5063</h4><pre style="backgroun
{
char const* p = piece_priority-&gt;string_ptr();
for (int i = 0; i &lt; piece_priority-&gt;string_length(); ++i)
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(51)">../src/torrent.cpp:5199</a></td><td>if this is a merkle torrent and we can't restore the tree, we need to wipe all the bits in the have array, but not necessarily we might want to do a full check to see if we have all the pieces. This is low priority since almost no one uses merkle torrents</td></tr><tr id="51" style="display: none;" colspan="3"><td colspan="3"><h2>if this is a merkle torrent and we can't
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(52)">../src/torrent.cpp:5199</a></td><td>if this is a merkle torrent and we can't restore the tree, we need to wipe all the bits in the have array, but not necessarily we might want to do a full check to see if we have all the pieces. This is low priority since almost no one uses merkle torrents</td></tr><tr id="52" style="display: none;" colspan="3"><td colspan="3"><h2>if this is a merkle torrent and we can't
restore the tree, we need to wipe all the
bits in the have array, but not necessarily
we might want to do a full check to see if we have
@ -2637,7 +2688,7 @@ no one uses merkle torrents</h2><h4>../src/torrent.cpp:5199</h4><pre style="back
ret["num_complete"] = m_complete;
ret["num_incomplete"] = m_incomplete;
ret["num_downloaded"] = m_downloaded;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(52)">../src/torrent.cpp:5387</a></td><td>make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance. using file_base</td></tr><tr id="52" style="display: none;" colspan="3"><td colspan="3"><h2>make this more generic to not just work if files have been
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(53)">../src/torrent.cpp:5387</a></td><td>make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance. using file_base</td></tr><tr id="53" style="display: none;" colspan="3"><td colspan="3"><h2>make this more generic to not just work if files have been
renamed, but also if they have been merged into a single file for instance.
using file_base</h2><h4>../src/torrent.cpp:5387</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> entry::string_type&amp; pieces = ret["pieces"].string();
pieces.resize(m_torrent_file-&gt;num_pieces());
@ -2690,7 +2741,7 @@ using file_base</h2><h4>../src/torrent.cpp:5387</h4><pre style="background: #f6f
error_code ec;
policy::peer const* p = *i;
address addr = p-&gt;address();
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(53)">../src/torrent.cpp:7937</a></td><td>go through the pieces we have and count the total number of downloaders we have. Only count peers that are interested in us since some peers might not send have messages for pieces we have it num_interested == 0, we need to pick a new piece</td></tr><tr id="53" style="display: none;" colspan="3"><td colspan="3"><h2>go through the pieces we have and count the total number
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(54)">../src/torrent.cpp:7937</a></td><td>go through the pieces we have and count the total number of downloaders we have. Only count peers that are interested in us since some peers might not send have messages for pieces we have it num_interested == 0, we need to pick a new piece</td></tr><tr id="54" style="display: none;" colspan="3"><td colspan="3"><h2>go through the pieces we have and count the total number
of downloaders we have. Only count peers that are interested in us
since some peers might not send have messages for pieces we have
it num_interested == 0, we need to pick a new piece</h2><h4>../src/torrent.cpp:7937</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> }
@ -2744,7 +2795,7 @@ it num_interested == 0, we need to pick a new piece</h2><h4>../src/torrent.cpp:7
{
m_picker-&gt;get_availability(avail_vec);
}
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(54)">../src/udp_tracker_connection.cpp:550</a></td><td>it would be more efficient to not use a string here. however, the problem is that some trackers will respond with actual strings. For example i2p trackers</td></tr><tr id="54" style="display: none;" colspan="3"><td colspan="3"><h2>it would be more efficient to not use a string here.
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(55)">../src/udp_tracker_connection.cpp:550</a></td><td>it would be more efficient to not use a string here. however, the problem is that some trackers will respond with actual strings. For example i2p trackers</td></tr><tr id="55" style="display: none;" colspan="3"><td colspan="3"><h2>it would be more efficient to not use a string here.
however, the problem is that some trackers will respond
with actual strings. For example i2p trackers</h2><h4>../src/udp_tracker_connection.cpp:550</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> }
@ -2797,7 +2848,7 @@ with actual strings. For example i2p trackers</h2><h4>../src/udp_tracker_connect
{
restart_read_timeout();
int action = detail::read_int32(buf);
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(55)">../src/utp_stream.cpp:1573</a></td><td>this loop may not be very efficient</td></tr><tr id="55" style="display: none;" colspan="3"><td colspan="3"><h2>this loop may not be very efficient</h2><h4>../src/utp_stream.cpp:1573</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> TORRENT_ASSERT(p-&gt;header_size &gt;= sizeof(utp_header) + sack_size + 2);
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(56)">../src/utp_stream.cpp:1573</a></td><td>this loop may not be very efficient</td></tr><tr id="56" style="display: none;" colspan="3"><td colspan="3"><h2>this loop may not be very efficient</h2><h4>../src/utp_stream.cpp:1573</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> TORRENT_ASSERT(p-&gt;header_size &gt;= sizeof(utp_header) + sack_size + 2);
memmove(ptr, ptr + sack_size + 2, p-&gt;size - p-&gt;header_size);
p-&gt;header_size -= sack_size + 2;
p-&gt;size -= sack_size + 2;
@ -2848,8 +2899,8 @@ bool utp_socket_impl::send_pkt(int flags)
if (sack &gt; 32) sack = 32;
}
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(56)">../src/kademlia/routing_table.cpp:291</a></td><td>instad of refreshing a bucket by using find_nodes, ping each node periodically</td></tr><tr id="56" style="display: none;" colspan="3"><td colspan="3"><h2>instad of refreshing a bucket by using find_nodes,
ping each node periodically</h2><h4>../src/kademlia/routing_table.cpp:291</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> os &lt;&lt; "]\n";
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(57)">../src/kademlia/routing_table.cpp:293</a></td><td>instad of refreshing a bucket by using find_nodes, ping each node periodically</td></tr><tr id="57" style="display: none;" colspan="3"><td colspan="3"><h2>instad of refreshing a bucket by using find_nodes,
ping each node periodically</h2><h4>../src/kademlia/routing_table.cpp:293</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> os &lt;&lt; "]\n";
}
}
@ -2871,6 +2922,8 @@ bool compare_bucket_refresh(routing_table_node const&amp; lhs, routing_table_nod
<div style="background: #ffff00" width="100%">bool routing_table::need_refresh(node_id&amp; target) const
</div>{
INVARIANT_CHECK;
ptime now = time_now();
// refresh our own bucket once every 15 minutes
@ -2898,9 +2951,7 @@ bool compare_bucket_refresh(routing_table_node const&amp; lhs, routing_table_nod
node_id mask = generate_prefix_mask(num_bits);
// target = (target &amp; ~mask) | (root &amp; mask)
node_id root = m_id;
root &amp;= mask;
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(57)">../include/libtorrent/config.hpp:326</a></td><td>Make this count Unicode characters instead of bytes on windows</td></tr><tr id="57" style="display: none;" colspan="3"><td colspan="3"><h2>Make this count Unicode characters instead of bytes on windows</h2><h4>../include/libtorrent/config.hpp:326</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(58)">../include/libtorrent/config.hpp:326</a></td><td>Make this count Unicode characters instead of bytes on windows</td></tr><tr id="58" style="display: none;" colspan="3"><td colspan="3"><h2>Make this count Unicode characters instead of bytes on windows</h2><h4>../include/libtorrent/config.hpp:326</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">
// ==== eCS(OS/2) ===
#elif defined __OS2__
#define TORRENT_OS2
@ -2951,57 +3002,6 @@ bool compare_bucket_refresh(routing_table_node const&amp; lhs, routing_table_nod
#include &lt;stdarg.h&gt;
// internal
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(58)">../include/libtorrent/entry.hpp:231</a></td><td>could this be removed?</td></tr><tr id="58" style="display: none;" colspan="3"><td colspan="3"><h2>could this be removed?</h2><h4>../include/libtorrent/entry.hpp:231</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> // existing element at the given key. If the key is not found, it will throw
// ``libtorrent::type_error``.
entry&amp; operator[](char const* key);
entry&amp; operator[](std::string const&amp; key);
#ifndef BOOST_NO_EXCEPTIONS
const entry&amp; operator[](char const* key) const;
const entry&amp; operator[](std::string const&amp; key) const;
#endif
// These functions requires the entry to be a dictionary, if it isn't they
// will throw ``libtorrent::type_error``.
//
// They will look for an element at the given key in the dictionary, if the
// element cannot be found, they will return 0. If an element with the given
// key is found, the return a pointer to it.
entry* find_key(char const* key);
entry const* find_key(char const* key) const;
entry* find_key(std::string const&amp; key);
entry const* find_key(std::string const&amp; key) const;
<div style="background: #ffff00" width="100%">#if (defined TORRENT_VERBOSE_LOGGING || defined TORRENT_DEBUG) &amp;&amp; TORRENT_USE_IOSTREAM
</div> void print(std::ostream&amp; os, int indent = 0) const;
#endif
protected:
void construct(data_type t);
void copy(const entry&amp; e);
void destruct();
private:
#if (defined(_MSC_VER) &amp;&amp; _MSC_VER &lt; 1310) || TORRENT_COMPLETE_TYPES_REQUIRED
// workaround for msvc-bug.
// assumes sizeof(map&lt;string, char&gt;) == sizeof(map&lt;string, entry&gt;)
// and sizeof(list&lt;char&gt;) == sizeof(list&lt;entry&gt;)
enum { union_size
= max4&lt;sizeof(std::list&lt;char&gt;)
, sizeof(std::map&lt;std::string, char&gt;)
, sizeof(string_type)
, sizeof(integer_type)&gt;::value
};
#else
enum { union_size
= max4&lt;sizeof(list_type)
, sizeof(dictionary_type)
, sizeof(string_type)
, sizeof(integer_type)&gt;::value
};
#endif
integer_type data[(union_size + sizeof(integer_type) - 1)
</pre></td></tr><tr style="background: #ccc"><td>relevance&nbsp;0</td><td><a href="javascript:expand(59)">../include/libtorrent/peer_connection.hpp:729</a></td><td>make this private</td></tr><tr id="59" style="display: none;" colspan="3"><td colspan="3"><h2>make this private</h2><h4>../include/libtorrent/peer_connection.hpp:729</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;"> void set_soft_packet_size(int size) { m_soft_packet_size = size; }
// if allow_encrypted is false, and the torrent 'ih' turns out