51
53
#include "protocol/peer_connection_base.h"
52
54
#include "protocol/peer_factory.h"
53
55
#include "download/download_info.h"
56
#include "peer/peer_info.h"
54
57
#include "tracker/tracker_manager.h"
56
59
#include "exceptions.h"
58
#include "block_list.h"
59
60
#include "download.h"
60
#include "file_list.h"
61
61
#include "object.h"
62
#include "peer_info.h"
63
62
#include "tracker_list.h"
65
64
namespace torrent {
81
80
Download::start() {
82
81
if (!m_ptr->hash_checker()->is_checked())
83
throw client_error("Tried to start an unchecked download");
82
throw internal_error("Tried to start an unchecked download.");
85
84
if (!m_ptr->info()->is_open())
86
throw client_error("Tried to start a closed download");
85
throw internal_error("Tried to start a closed download.");
88
87
if (m_ptr->info()->is_active())
121
120
Download::hash_check(bool tryQuick) {
122
121
if (m_ptr->hash_checker()->is_checking())
123
return m_ptr->hash_checker()->start(tryQuick);
122
throw internal_error("Download::hash_check(...) called but the hash is already being checked.");
125
124
if (!m_ptr->info()->is_open() || m_ptr->info()->is_active())
126
throw client_error("Download::hash_check(...) called on a closed or active download.");
125
throw internal_error("Download::hash_check(...) called on a closed or active download.");
128
127
if (m_ptr->hash_checker()->is_checked())
129
throw client_error("Download::hash_check(...) called but already hash checked.");
131
// The bitfield still hasn't been allocated, so no resume data was
134
if (m_ptr->main()->content()->bitfield()->empty()) {
135
m_ptr->main()->content()->bitfield()->allocate();
136
m_ptr->main()->content()->bitfield()->unset_all();
138
m_ptr->hash_checker()->ranges().insert(0, m_ptr->main()->content()->chunk_total());
140
// Make sure other book-keeping is cleared, like file progress.
143
m_ptr->main()->content()->update_done();
128
throw internal_error("Download::hash_check(...) called but already hash checked.");
130
Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
132
if (bitfield->empty()) {
133
// The bitfield still hasn't been allocated, so no resume data was
135
bitfield->allocate();
136
bitfield->unset_all();
138
m_ptr->hash_checker()->ranges().insert(0, m_ptr->main()->file_list()->size_chunks());
141
m_ptr->main()->file_list()->update_completed();
146
143
return m_ptr->hash_checker()->start(tryQuick);
152
149
if (!m_ptr->hash_checker()->is_checking())
155
// Stop the hashing first as we need to make sure all chunks are
156
// released when DownloadMain::close() is called.
152
m_ptr->hash_checker()->ranges().erase(0, m_ptr->hash_checker()->position());
153
m_ptr->hash_queue()->remove(m_ptr);
157
155
m_ptr->hash_checker()->clear();
159
// Clear after m_hash to ensure that the empty hash done signal does
160
// not get passed to HashTorrent.
161
m_ptr->hash_checker()->get_queue()->remove(m_ptr);
189
183
return m_ptr->info()->name();
193
187
Download::info_hash() const {
195
throw internal_error("Download::info_hash() m_ptr == NULL.");
197
188
return m_ptr->info()->hash();
192
Download::info_hash_obfuscated() const {
193
return m_ptr->info()->hash_obfuscated();
201
197
Download::local_id() const {
203
throw internal_error("Download::local_id() m_ptr == NULL.");
205
198
return m_ptr->info()->local_id();
267
265
return m_ptr->info()->up_rate();
269
Download::mutable_up_rate() {
270
return m_ptr->info()->up_rate();
274
Download::skip_rate() {
275
return m_ptr->info()->skip_rate();
279
Download::skip_rate() const {
280
return m_ptr->info()->skip_rate();
284
Download::mutable_skip_rate() {
285
return m_ptr->info()->skip_rate();
271
289
Download::bytes_done() const {
278
296
if (itr2->is_finished())
279
297
a += itr2->piece().length();
281
return a + m_ptr->main()->content()->bytes_completed();
285
Download::bytes_total() const {
286
return m_ptr->main()->content()->entry_list()->bytes_size();
290
Download::free_diskspace() const {
291
return m_ptr->main()->content()->entry_list()->free_diskspace();
295
Download::chunks_size() const {
296
return m_ptr->main()->content()->chunk_size();
300
Download::chunks_done() const {
301
return m_ptr->main()->content()->chunks_completed();
305
Download::chunks_total() const {
306
return m_ptr->main()->content()->chunk_total();
299
return a + m_ptr->main()->file_list()->completed_bytes();
321
314
if (m_ptr->info()->is_open())
322
315
throw input_error("Download::set_chunks_done(...) Download is open.");
324
m_ptr->main()->content()->bitfield()->set_size_set(chunks);
317
m_ptr->main()->file_list()->mutable_bitfield()->set_size_set(chunks);
329
322
if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())
330
323
throw input_error("Download::set_bitfield(...) Download in invalid state.");
332
Bitfield* bitfield = m_ptr->main()->content()->bitfield();
325
Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
334
327
bitfield->allocate();
346
339
if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())
347
340
throw input_error("Download::set_bitfield(...) Download in invalid state.");
349
if (std::distance(first, last) != (ptrdiff_t)m_ptr->main()->content()->bitfield()->size_bytes())
342
if (std::distance(first, last) != (ptrdiff_t)m_ptr->main()->file_list()->bitfield()->size_bytes())
350
343
throw input_error("Download::set_bitfield(...) Invalid length.");
352
Bitfield* bitfield = m_ptr->main()->content()->bitfield();
345
Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
354
347
bitfield->allocate();
355
348
std::memcpy(bitfield->begin(), first, bitfield->size_bytes());
362
355
Download::clear_range(uint32_t first, uint32_t last) {
363
if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking() || m_ptr->main()->content()->bitfield()->empty())
356
if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking() || m_ptr->main()->file_list()->bitfield()->empty())
364
357
throw input_error("Download::clear_range(...) Download in invalid state.");
359
// Unset progress of any files.
366
361
m_ptr->hash_checker()->ranges().insert(first, last);
367
m_ptr->main()->content()->bitfield()->unset_range(first, last);
362
m_ptr->main()->file_list()->mutable_bitfield()->unset_range(first, last);
371
Download::bitfield() const {
372
return m_ptr->main()->content()->bitfield();
376
366
Download::sync_chunks() {
377
367
m_ptr->main()->chunk_list()->sync_chunks(ChunkList::sync_all | ChunkList::sync_force);
411
401
Download::peers_currently_unchoked() const {
412
return m_ptr->main()->choke_manager()->currently_unchoked();
402
return m_ptr->main()->upload_choke_manager()->size_unchoked();
416
406
Download::peers_currently_interested() const {
417
return m_ptr->main()->choke_manager()->currently_interested();
407
return m_ptr->main()->upload_choke_manager()->size_total();
449
439
if (v > (1 << 16))
450
440
throw input_error("Max uploads must be between 0 and 2^16.");
452
m_ptr->main()->choke_manager()->set_max_unchoked(v);
453
m_ptr->main()->choke_manager()->balance();
442
// For the moment, treat 0 as unlimited.
443
m_ptr->main()->upload_choke_manager()->set_max_unchoked(v == 0 ? ChokeManager::unlimited : v);
444
m_ptr->main()->upload_choke_manager()->balance();
456
447
Download::ConnectionType
489
480
Download::peer_find(const std::string& id) {
490
481
ConnectionList::iterator itr =
491
482
std::find_if(m_ptr->main()->connection_list()->begin(), m_ptr->main()->connection_list()->end(),
492
rak::equal(id, rak::on(std::mem_fun(&PeerConnectionBase::c_peer_info), std::mem_fun(&PeerInfo::id))));
483
rak::equal(*HashString::cast_from(id), rak::on(std::mem_fun(&PeerConnectionBase::c_peer_info), std::mem_fun(&PeerInfo::id))));
494
485
return itr != m_ptr->main()->connection_list()->end() ? *itr : NULL;