*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-01-24 17:14:03 +00:00
parent 88f1d8200a
commit 19a4dad706
16 changed files with 341 additions and 109 deletions

View File

@ -14,56 +14,59 @@
<p class="topic-title"><a name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#introduction" id="id9" name="id9">introduction</a></li>
<li><a class="reference" href="#building" id="id10" name="id10">building</a></li>
<li><a class="reference" href="#using" id="id11" name="id11">using</a></li>
<li><a class="reference" href="#session" id="id12" name="id12">session</a></li>
<li><a class="reference" href="#parsing-torrent-files" id="id13" name="id13">parsing torrent files</a></li>
<li><a class="reference" href="#entry" id="id14" name="id14">entry</a></li>
<li><a class="reference" href="#torrent-info" id="id15" name="id15">torrent_info</a></li>
<li><a class="reference" href="#torrent-handle" id="id16" name="id16">torrent_handle</a><ul>
<li><a class="reference" href="#status" id="id17" name="id17">status()</a></li>
<li><a class="reference" href="#get-download-queue" id="id18" name="id18">get_download_queue()</a></li>
<li><a class="reference" href="#get-peer-info" id="id19" name="id19">get_peer_info()</a></li>
<li><a class="reference" href="#get-torrent-info" id="id20" name="id20">get_torrent_info()</a></li>
<li><a class="reference" href="#is-valid" id="id21" name="id21">is_valid()</a></li>
<li><a class="reference" href="#building" id="id10" name="id10">building</a><ul>
<li><a class="reference" href="#release-and-debug-builds" id="id11" name="id11">release and debug builds</a></li>
</ul>
</li>
<li><a class="reference" href="#address" id="id22" name="id22">address</a></li>
<li><a class="reference" href="#http-settings" id="id23" name="id23">http_settings</a></li>
<li><a class="reference" href="#big-number" id="id24" name="id24">big_number</a></li>
<li><a class="reference" href="#hasher" id="id25" name="id25">hasher</a></li>
<li><a class="reference" href="#fingerprint" id="id26" name="id26">fingerprint</a><ul>
<li><a class="reference" href="#identify-client" id="id27" name="id27">identify_client</a></li>
<li><a class="reference" href="#using" id="id12" name="id12">using</a></li>
<li><a class="reference" href="#session" id="id13" name="id13">session</a></li>
<li><a class="reference" href="#parsing-torrent-files" id="id14" name="id14">parsing torrent files</a></li>
<li><a class="reference" href="#entry" id="id15" name="id15">entry</a></li>
<li><a class="reference" href="#torrent-info" id="id16" name="id16">torrent_info</a></li>
<li><a class="reference" href="#torrent-handle" id="id17" name="id17">torrent_handle</a><ul>
<li><a class="reference" href="#status" id="id18" name="id18">status()</a></li>
<li><a class="reference" href="#get-download-queue" id="id19" name="id19">get_download_queue()</a></li>
<li><a class="reference" href="#get-peer-info" id="id20" name="id20">get_peer_info()</a></li>
<li><a class="reference" href="#get-torrent-info" id="id21" name="id21">get_torrent_info()</a></li>
<li><a class="reference" href="#is-valid" id="id22" name="id22">is_valid()</a></li>
</ul>
</li>
<li><a class="reference" href="#alerts" id="id28" name="id28">alerts</a><ul>
<li><a class="reference" href="#tracker-alert" id="id29" name="id29">tracker_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id30" name="id30">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id31" name="id31">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id32" name="id32">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id33" name="id33">torrent_finished_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id34" name="id34">dispatcher</a></li>
<li><a class="reference" href="#address" id="id23" name="id23">address</a></li>
<li><a class="reference" href="#http-settings" id="id24" name="id24">http_settings</a></li>
<li><a class="reference" href="#big-number" id="id25" name="id25">big_number</a></li>
<li><a class="reference" href="#hasher" id="id26" name="id26">hasher</a></li>
<li><a class="reference" href="#fingerprint" id="id27" name="id27">fingerprint</a><ul>
<li><a class="reference" href="#identify-client" id="id28" name="id28">identify_client</a></li>
</ul>
</li>
<li><a class="reference" href="#exceptions" id="id35" name="id35">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id36" name="id36">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id37" name="id37">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id38" name="id38">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id39" name="id39">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id40" name="id40">invalid_torrent_file</a></li>
<li><a class="reference" href="#alerts" id="id29" name="id29">alerts</a><ul>
<li><a class="reference" href="#tracker-alert" id="id30" name="id30">tracker_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id31" name="id31">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id32" name="id32">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id33" name="id33">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id34" name="id34">torrent_finished_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id35" name="id35">dispatcher</a></li>
</ul>
</li>
<li><a class="reference" href="#examples" id="id41" name="id41">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id42" name="id42">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id43" name="id43">simple client</a></li>
<li><a class="reference" href="#exceptions" id="id36" name="id36">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id37" name="id37">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id38" name="id38">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id39" name="id39">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id40" name="id40">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id41" name="id41">invalid_torrent_file</a></li>
</ul>
</li>
<li><a class="reference" href="#fast-resume" id="id44" name="id44">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id45" name="id45">file format</a></li>
<li><a class="reference" href="#examples" id="id42" name="id42">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id43" name="id43">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id44" name="id44">simple client</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id46" name="id46">extensions</a></li>
<li><a class="reference" href="#aknowledgements" id="id47" name="id47">aknowledgements</a></li>
<li><a class="reference" href="#fast-resume" id="id45" name="id45">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id46" name="id46">file format</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id47" name="id47">extensions</a></li>
<li><a class="reference" href="#aknowledgements" id="id48" name="id48">aknowledgements</a></li>
</ul>
</div>
<div class="section" id="introduction">
@ -105,6 +108,8 @@ peers in a separate fast-resume file.</li>
<li>supports the <tt class="literal"><span class="pre">no_peer_id=1</span></tt> extension that will ease the load off trackers.</li>
<li>supports the <a class="reference" href="udp_tracker_protocol.html">udp-tracker protocol</a>.</li>
<li>possibility to limit the number of connections.</li>
<li>delays have messages if there's no other outgoing traffic to the peer, and doesn't
send have messages to peers that already has the piece. This saves bandwidth.</li>
</ul>
</blockquote>
<p>Functions that are yet to be implemented:</p>
@ -136,9 +141,6 @@ boost.filesystem, boost.date_time and various other boost libraries as well as z
</div>
<div class="section" id="building">
<h1><a name="building">building</a></h1>
<p>Whwn building in release mode you need to define NDEBUG in order to avoid
all asserts and invariant checks within libtorrent. Developer studio does
this by default.</p>
<p>To build libtorrent you need <a class="reference" href="http://www.boost.org">boost</a> and bjam installed.
Then you can use <tt class="literal"><span class="pre">bjam</span></tt> to build libtorrent.</p>
<p>To make bjam work, you need to set the environment variable <tt class="literal"><span class="pre">BOOST_ROOT</span></tt> to the
@ -168,6 +170,46 @@ of the file:</p>
<p>In developer studio, you may have to set the compiler options &quot;force conformance in for
loop scope&quot; and &quot;treat wchar_t as built-in type&quot; to Yes.</p>
<p>TODO: more detailed build instructions.</p>
<div class="section" id="release-and-debug-builds">
<h2><a name="release-and-debug-builds">release and debug builds</a></h2>
<p>If you just invoke the makefile you'll get a debug build. In debug the libtorrent vill
have pretty expensive invariant checks and asserts built into it. If you want to disable
such checks (you want to do that in a release build) you can see the table below for which
defines you can use to control the build.</p>
<table border class="table">
<colgroup>
<col width="39%" />
<col width="61%" />
</colgroup>
<thead valign="bottom">
<tr><th>macro</th>
<th>description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">NDEBUG</span></tt></td>
<td>If you define this macro, all asserts,
invariant checks and general debug code will be
removed. This option takes precedence over
other debug settings.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">TORRENT_VERBOSE_LOGGING</span></tt></td>
<td>If you define this macro, every peer connection
will log its traffic to a log file.
This setting requires a debug build, i.e.
if you set <tt class="literal"><span class="pre">NDEBUG</span></tt> aswell, no logs will be
written.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">TORRENT_STORAGE_DEBUG</span></tt></td>
<td>This will enable extra expensive invariant
checks in the storage, including logging of
piece sorting.</td>
</tr>
</tbody>
</table>
<p>If you experience that libtorrent uses unreasonable amounts of cpu, it will definately help to
define <tt class="literal"><span class="pre">NDEBUG</span></tt>.</p>
</div>
</div>
<div class="section" id="using">
<h1><a name="using">using</a></h1>

View File

@ -42,6 +42,8 @@ The current state includes the following features:
* supports the ``no_peer_id=1`` extension that will ease the load off trackers.
* supports the `udp-tracker protocol`__.
* possibility to limit the number of connections.
* delays have messages if there's no other outgoing traffic to the peer, and doesn't
send have messages to peers that already has the piece. This saves bandwidth.
__ http://home.elp.rr.com/tur/multitracker-spec.txt
.. _Azureus: http://azureus.sourceforge.net
@ -77,11 +79,6 @@ libtorrent is released under the BSD-license_.
building
========
Whwn building in release mode you need to define NDEBUG in order to avoid
all asserts and invariant checks within libtorrent. Developer studio does
this by default.
To build libtorrent you need boost_ and bjam installed.
Then you can use ``bjam`` to build libtorrent.
@ -122,6 +119,37 @@ loop scope" and "treat wchar_t as built-in type" to Yes.
TODO: more detailed build instructions.
release and debug builds
------------------------
If you just invoke the makefile you'll get a debug build. In debug the libtorrent vill
have pretty expensive invariant checks and asserts built into it. If you want to disable
such checks (you want to do that in a release build) you can see the table below for which
defines you can use to control the build.
+-------------------------------+-------------------------------------------------+
| macro | description |
+===============================+=================================================+
| ``NDEBUG`` | If you define this macro, all asserts, |
| | invariant checks and general debug code will be |
| | removed. This option takes precedence over |
| | other debug settings. |
+-------------------------------+-------------------------------------------------+
| ``TORRENT_VERBOSE_LOGGING`` | If you define this macro, every peer connection |
| | will log its traffic to a log file. |
| | This setting requires a debug build, i.e. |
| | if you set ``NDEBUG`` aswell, no logs will be |
| | written. |
+-------------------------------+-------------------------------------------------+
| ``TORRENT_STORAGE_DEBUG`` | This will enable extra expensive invariant |
| | checks in the storage, including logging of |
| | piece sorting. |
+-------------------------------+-------------------------------------------------+
If you experience that libtorrent uses unreasonable amounts of cpu, it will definately help to
define ``NDEBUG``.

View File

@ -400,7 +400,7 @@ int main(int argc, char* argv[])
}
*/
}
/*
out << "___________________________________\n";
i->get_download_queue(queue);
@ -421,7 +421,7 @@ int main(int argc, char* argv[])
}
out << "___________________________________\n";
*/
}
for (std::deque<std::string>::iterator i = events.begin();

View File

@ -80,6 +80,7 @@ namespace libtorrent
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_error_alert(*this)); }
// TODO: use address instead of peer_id
peer_id id;
};
@ -98,6 +99,7 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new chat_message_alert(*this)); }
torrent_handle handle;
// TODO: use address instead of peer_id
peer_id sender;
};
@ -118,6 +120,7 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new invalid_request_alert(*this)); }
torrent_handle handle;
// TODO: use address instead of peer_id
peer_id sender;
peer_request request;
};

View File

@ -41,14 +41,34 @@ extern "C"
unsigned char buffer[64];
} SHA1_CTX;
/* from sha1.c */
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
void SHA1Final(unsigned char* digest, SHA1_CTX* context);
/* from zlib/adler32.c */
unsigned long adler32(unsigned long adler, const char* data, unsigned int len);
}
namespace libtorrent
{
class adler32_crc
{
public:
adler32_crc(): m_adler(adler32(0, 0, 0)) {}
void update(const char* data, int len)
{ m_adler = adler32(m_adler, data, len); }
unsigned long final() const { return m_adler; }
void reset() { m_adler = adler32(0, 0, 0); }
private:
unsigned long m_adler;
};
class hasher
{
public:

View File

@ -220,7 +220,6 @@ namespace libtorrent
void announce_piece(int index)
{
m_announce_queue.push_back(index);
send_buffer_updated();
}
// called from the main loop when this connection has any

View File

@ -92,7 +92,7 @@ namespace libtorrent
// info about each block
block_info info[max_blocks_per_piece];
// TODO: store a hash and a peer_connection reference
// TODO: store a crc and a peer_connection reference
// for each block. Then if the hash test fails on the
// piece, redownload one block from another peer
// then the first time, and check the hash again.

View File

@ -72,13 +72,15 @@ namespace libtorrent
// workaround for microsofts
// hardware exceptions that makes
// it hard to debug stuff
#if !defined(NDEBUG) && defined(_MSC_VER)
#if defined(_MSC_VER)
struct eh_initializer
{
eh_initializer()
{
#ifndef NDEBUG
_clearfp();
_controlfp(_EM_INEXACT | _EM_UNDERFLOW, _MCW_EM );
#endif
::_set_se_translator(straight_to_debugger);
}

View File

@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_STORAGE_HPP_INCLUDE
#include <vector>
#include <bitset>
#include <boost/limits.hpp>
#include <boost/filesystem/path.hpp>
@ -103,6 +104,12 @@ namespace libtorrent
void allocate_slots(int num_slots);
void mark_failed(int index);
unsigned long piece_crc(
int slot_index
, int block_size
, const std::bitset<256>& bitmask);
int slot_for_piece(int piece_index) const;
size_type read(char* buf, int piece_index, size_type offset, size_type size);
void write(const char* buf, int piece_index, size_type offset, size_type size);

View File

@ -201,6 +201,12 @@ namespace libtorrent
// non standard encodings
// ----------------------
if (std::equal(PID, PID + 4, "exbc"))
{
std::stringstream s;
s << "BitComet " << (int)PID[4] << "." << (int)PID[5]/10 << (int)PID[5]%10;
return s.str();
}
if (std::equal(PID + 5, PID + 5 + 8, "Azureus"))
{
@ -214,7 +220,7 @@ namespace libtorrent
if (std::equal(PID, PID + 7, "btfans"))
{
return "BitComet";
return "SimpleBT";
}
if (std::equal(PID, PID + 8, "turbobt"))

View File

@ -1455,8 +1455,7 @@ namespace libtorrent
// if we have requests or pending data to be sent or announcements to be made
// we want to send data
return ((!m_requests.empty() && !m_choked)
|| !m_send_buffer.empty()
|| !m_announce_queue.empty())
|| !m_send_buffer.empty())
&& m_send_quota_left != 0;
}
@ -1634,7 +1633,11 @@ namespace libtorrent
{
boost::posix_time::time_duration d;
d = boost::posix_time::second_clock::local_time() - m_last_sent;
if (d.seconds() > m_timeout / 2)
if (d.seconds() < m_timeout / 2) return;
// we must either send a keep-alive
// message or something else.
if (m_announce_queue.empty())
{
char noop[] = {0,0,0,0};
m_send_buffer.insert(m_send_buffer.end(), noop, noop+4);
@ -1642,11 +1645,23 @@ namespace libtorrent
#ifndef NDEBUG
(*m_logger) << " ==> NOP\n";
#endif
send_buffer_updated();
}
else
{
for (std::vector<int>::iterator i = m_announce_queue.begin();
i != m_announce_queue.end();
++i)
{
send_have(*i);
}
m_announce_queue.clear();
}
send_buffer_updated();
}
// TODO: this could be implemented more efficient
// by maintaining a counter of the number of pieces
// the peer has
bool peer_connection::is_seed() const
{
return std::count(m_have_piece.begin(), m_have_piece.end(), true)

View File

@ -280,13 +280,6 @@ namespace
namespace libtorrent
{
/*
TODO: implement some kind of limit of the number of sockets
opened, to use for systems where a user has a limited number
of open file descriptors. and for windows which has a buggy tcp-stack.
This means also to implement a 'connecion purger', that identifies
more or less useless connections and closes them.
*/
policy::policy(torrent* t)
: m_num_peers(0)
@ -624,6 +617,8 @@ namespace libtorrent
{
assert(!c.is_local());
// TODO: make an exception if the incoming connection
// is from the tracker
if(m_torrent->num_peers() >= m_max_connections)
throw protocol_error("too many connections, refusing incoming connection"); // cause a disconnect
@ -893,6 +888,7 @@ namespace libtorrent
{
assert(max_connections > 1 || max_connections == -1);
if (max_connections == -1) max_connections = std::numeric_limits<int>::max();
assert(max_connections >= 2);
m_max_connections = max_connections;
}

View File

@ -378,6 +378,7 @@ namespace libtorrent
{
m_connections.erase(m_disconnect_peer.back());
m_disconnect_peer.pop_back();
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
}
}
@ -500,12 +501,19 @@ namespace libtorrent
assert(p->second->get_socket()->is_writable());
p->second->send_data();
}
catch(std::exception&)
catch(std::exception& e)
{
// the connection wants to disconnect for some reason, remove it
// from the connection-list
// the connection wants to disconnect for some reason,
// remove it from the connection-list
if (m_alerts.should_post(alert::debug))
{
m_alerts.post_alert(
peer_error_alert(p->second->get_peer_id(), e.what()));
}
m_selector.remove(*i);
m_connections.erase(p);
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
}
}
}
@ -558,10 +566,6 @@ namespace libtorrent
{
// (*m_logger) << "readable: " << p->first->sender().as_string() << "\n";
p->second->receive_data();
#ifndef NDEBUG
assert_invariant();
#endif
}
catch(std::exception& e)
{
@ -574,6 +578,7 @@ namespace libtorrent
// from the connection-list
m_selector.remove(*i);
m_connections.erase(p);
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
}
}
}
@ -593,10 +598,21 @@ namespace libtorrent
++i)
{
connection_map::iterator p = m_connections.find(*i);
if (m_alerts.should_post(alert::debug))
{
m_alerts.post_alert(
peer_error_alert(
p->second->get_peer_id()
, "socket received an exception"));
}
m_selector.remove(*i);
// the connection may have been disconnected in the receive or send phase
if (p != m_connections.end()) m_connections.erase(p);
if (p != m_connections.end())
{
m_connections.erase(p);
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
}
}
#ifndef NDEBUG
@ -631,6 +647,7 @@ namespace libtorrent
{
m_selector.remove(j->first);
m_connections.erase(j);
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
continue;
}
@ -1018,6 +1035,34 @@ namespace libtorrent
p.finished_blocks[bit] = true;
}
}
if (p.finished_blocks.count() == 0) continue;
std::vector<int>::iterator slot_iter
= std::find(tmp_pieces.begin(), tmp_pieces.end(), p.index);
if (slot_iter == tmp_pieces.end())
{
// this piece is marked as unfinished
// but doesn't have any storage
return;
}
assert(*slot_iter == p.index);
int slot_index = slot_iter - tmp_pieces.begin();
unsigned long adler
= torrent_ptr->filesystem().piece_crc(
slot_index
, torrent_ptr->block_size()
, p.finished_blocks);
entry::dictionary_type::iterator ad = i->dict().find("adler32");
if (ad != i->dict().end())
{
// crc's didn't match, don't use the resume data
if (ad->second.integer() != adler)
return;
}
tmp_unfinished.push_back(p);
}

View File

@ -427,6 +427,13 @@ namespace libtorrent
void allocate_slots(int num_slots);
void mark_failed(int index);
unsigned long piece_crc(
int slot_index
, int block_size
, const std::bitset<256>& bitmask);
int slot_for_piece(int piece_index) const;
size_type read(char* buf, int piece_index, size_type offset, size_type size);
void write(const char* buf, int piece_index, size_type offset, size_type size);
@ -438,17 +445,15 @@ namespace libtorrent
private:
// returns the slot currently associated with the given
// piece or assigns the given piece_index to a free slot
int slot_for_piece(int piece_index);
int allocate_slot_for_piece(int piece_index);
#ifndef NDEBUG
void check_invariant() const;
#ifdef TORRENT_STORAGE_DEBUG
void debug_log() const;
#endif
#endif
storage m_storage;
// total number of bytes left to be downloaded
// TODO: this member shouldn't be necessaty any more
size_type m_bytes_left;
// a bitmask representing the pieces we have
std::vector<bool> m_have_piece;
@ -571,6 +576,57 @@ namespace libtorrent
m_pimpl->mark_failed(index);
}
int piece_manager::slot_for_piece(int piece_index) const
{
return m_pimpl->slot_for_piece(piece_index);
}
int piece_manager::impl::slot_for_piece(int piece_index) const
{
assert(piece_index >= 0 && piece_index < m_info.num_pieces());
return m_piece_to_slot[piece_index];
}
unsigned long piece_manager::piece_crc(
int index
, int block_size
, const std::bitset<256>& bitmask)
{
return m_pimpl->piece_crc(index, block_size, bitmask);
}
unsigned long piece_manager::impl::piece_crc(
int slot_index
, int block_size
, const std::bitset<256>& bitmask)
{
adler32_crc crc;
std::vector<char> buf(block_size);
int num_blocks = m_info.piece_size(slot_index) / block_size;
int last_block_size = m_info.piece_size(slot_index) % block_size;
if (last_block_size == 0) last_block_size = block_size;
for (int i = 0; i < num_blocks-1; ++i)
{
if (!bitmask[i]) continue;
m_storage.read(
&buf[0]
, slot_index
, i * block_size
, block_size);
crc.update(&buf[0], block_size);
}
if (bitmask[num_blocks - 1])
{
m_storage.read(
&buf[0]
, slot_index
, block_size * (num_blocks - 1)
, last_block_size);
crc.update(&buf[0], last_block_size);
}
return crc.final();
}
size_type piece_manager::impl::read(
char* buf
@ -598,7 +654,7 @@ namespace libtorrent
, size_type offset
, size_type size)
{
int slot = slot_for_piece(piece_index);
int slot = allocate_slot_for_piece(piece_index);
m_storage.write(buf, slot, offset, size);
}
@ -626,8 +682,6 @@ namespace libtorrent
m_piece_to_slot.resize(m_info.num_pieces(), has_no_slot);
m_slot_to_piece.resize(m_info.num_pieces(), unallocated);
m_bytes_left = m_info.total_size();
const std::size_t piece_size = m_info.piece_length();
const std::size_t last_piece_size = m_info.piece_size(
m_info.num_pieces() - 1);
@ -655,7 +709,6 @@ namespace libtorrent
, piece_picker::has_index(found_piece))
== data.unfinished_pieces.end())
{
m_bytes_left -= m_info.piece_size(found_piece);
pieces[found_piece] = true;
}
}
@ -832,10 +885,6 @@ namespace libtorrent
m_slot_to_piece[m_piece_to_slot[found_piece]] = unassigned;
m_free_slots.push_back(m_piece_to_slot[found_piece]);
}
else
{
m_bytes_left -= m_info.piece_size(found_piece);
}
m_piece_to_slot[found_piece] = current_slot;
m_slot_to_piece[current_slot] = found_piece;
@ -892,7 +941,7 @@ namespace libtorrent
m_pimpl->check_pieces(mutex, data, pieces);
}
int piece_manager::impl::slot_for_piece(int piece_index)
int piece_manager::impl::allocate_slot_for_piece(int piece_index)
{
// synchronization ------------------------------------------------------
boost::recursive_mutex::scoped_lock lock(m_mutex);
@ -979,7 +1028,9 @@ namespace libtorrent
assert(m_piece_to_slot[piece_at_our_slot] == piece_index);
#ifndef NDEBUG
print_to_log(s.str());
#ifdef TORRENT_STORAGE_DEBUG
debug_log();
#endif
#endif
std::swap(
m_slot_to_piece[piece_index]
@ -997,7 +1048,7 @@ namespace libtorrent
assert(m_piece_to_slot[piece_index] == piece_index);
slot_index = piece_index;
#ifndef NDEBUG
#if !defined(NDEBUG) && defined(TORRENT_STORAGE_DEBUG)
debug_log();
#endif
}
@ -1098,7 +1149,8 @@ namespace libtorrent
{
assert(m_slot_to_piece[i]<m_piece_to_slot.size());
assert(m_piece_to_slot[m_slot_to_piece[i]]==i);
/* assert(
#ifdef TORRENT_STORAGE_DEBUG
assert(
std::find(
m_unallocated_slots.begin()
, m_unallocated_slots.end()
@ -1110,25 +1162,30 @@ namespace libtorrent
, m_free_slots.end()
, i) == m_free_slots.end()
);
*/ }
#endif
}
else if (m_slot_to_piece[i] == unallocated)
{
/* assert(
#ifdef TORRENT_STORAGE_DEBUG
assert(
std::find(
m_unallocated_slots.begin()
, m_unallocated_slots.end()
, i) != m_unallocated_slots.end()
);
*/ }
#endif
}
else if (m_slot_to_piece[i] == unassigned)
{
/* assert(
#ifdef TORRENT_STORAGE_DEBUG
assert(
std::find(
m_free_slots.begin()
, m_free_slots.end()
, i) != m_free_slots.end()
);
*/ }
#endif
}
else
{
assert(false && "m_slot_to_piece[i] is invalid");
@ -1136,6 +1193,7 @@ namespace libtorrent
}
}
#ifdef TORRENT_STORAGE_DEBUG
void piece_manager::impl::debug_log() const
{
std::stringstream s;
@ -1153,5 +1211,6 @@ namespace libtorrent
print_to_log(s.str());
}
#endif
#endif
} // namespace libtorrent

View File

@ -94,7 +94,6 @@ namespace libtorrent
void torrent_handle::set_max_connections(int max_connections)
{
assert(max_connections >= 2);
if (m_ses == 0) throw invalid_handle();
{
@ -240,13 +239,17 @@ namespace libtorrent
i != q.end();
++i)
{
if (i->finished_blocks.count() == 0) continue;
entry::dictionary_type piece_struct;
// the unfinished piece's index
piece_struct["piece"] = i->index;
std::string bitmask;
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
const int num_bitmask_bytes
= std::max(num_blocks_per_piece / 8, 1);
for (int j = 0; j < num_bitmask_bytes; ++j)
{
unsigned char v = 0;
@ -256,7 +259,14 @@ namespace libtorrent
}
piece_struct["bitmask"] = bitmask;
// TODO: add a hash to piece_struct
assert(t->filesystem().slot_for_piece(i->index) >= 0);
unsigned long adler
= t->filesystem().piece_crc(
t->filesystem().slot_for_piece(i->index)
, t->block_size()
, i->finished_blocks);
piece_struct["adler32"] = adler;
// push the struct onto the unfinished-piece list
up.push_back(piece_struct);

View File

@ -131,6 +131,20 @@ namespace libtorrent
m_urls.push_back(e);
}
// extract creation date
i = dict.find("creation date");
if (i != dict.end() && i->second.type() == entry::int_t)
{
m_creation_date = m_creation_date + boost::posix_time::seconds(i->second.integer());
}
// extract comment
i = dict.find("comment");
if (i != dict.end() && i->second.type() == entry::string_t)
{
m_comment = i->second.string();
}
i = dict.find("info");
if (i == dict.end()) throw invalid_torrent_file();
entry info = i->second;
@ -170,20 +184,6 @@ namespace libtorrent
extract_files(i->second.list(), m_files, m_name);
}
// extract creation date
i = info.dict().find("creation date");
if (i != info.dict().end() && i->second.type() == entry::int_t)
{
m_creation_date = m_creation_date + boost::posix_time::seconds(i->second.integer());
}
// extract comment
i = info.dict().find("comment");
if (i != info.dict().end() && i->second.type() == entry::string_t)
{
m_comment = i->second.string();
}
// calculate total size of all pieces
m_total_size = 0;
for (std::vector<file_entry>::iterator i = m_files.begin(); i != m_files.end(); ++i)