~ubuntu-branches/debian/experimental/libtorrent/experimental

« back to all changes in this revision

Viewing changes to src/torrent/download.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jose Luis Rivas
  • Date: 2007-03-31 10:31:05 UTC
  • mto: (4.1.4 gutsy) (6.2.1 squeeze) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: james.westby@ubuntu.com-20070331103105-jzpp1rml6ud0ff75
Tags: upstream-0.11.4
ImportĀ upstreamĀ versionĀ 0.11.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include <sigc++/bind.h>
41
41
#include <sigc++/hide.h>
42
42
 
 
43
#include "data/block.h"
 
44
#include "data/block_list.h"
43
45
#include "data/chunk_list.h"
44
46
#include "data/hash_queue.h"
45
47
#include "data/hash_torrent.h"
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"
55
58
 
56
59
#include "exceptions.h"
57
 
#include "block.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"
64
63
 
65
64
namespace torrent {
80
79
void
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.");
84
83
 
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.");
87
86
 
88
87
  if (m_ptr->info()->is_active())
89
88
    return;
120
119
bool
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.");
124
123
 
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.");
127
126
 
128
127
  if (m_ptr->hash_checker()->is_checked())
129
 
    throw client_error("Download::hash_check(...) called but already hash checked.");
130
 
 
131
 
  // The bitfield still hasn't been allocated, so no resume data was
132
 
  // given. 
133
 
 
134
 
  if (m_ptr->main()->content()->bitfield()->empty()) {
135
 
    m_ptr->main()->content()->bitfield()->allocate();
136
 
    m_ptr->main()->content()->bitfield()->unset_all();
137
 
 
138
 
    m_ptr->hash_checker()->ranges().insert(0, m_ptr->main()->content()->chunk_total());
139
 
 
140
 
    // Make sure other book-keeping is cleared, like file progress.
141
 
 
142
 
  } else {
143
 
    m_ptr->main()->content()->update_done();
 
128
    throw internal_error("Download::hash_check(...) called but already hash checked.");
 
129
 
 
130
  Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
 
131
 
 
132
  if (bitfield->empty()) {
 
133
    // The bitfield still hasn't been allocated, so no resume data was
 
134
    // given. 
 
135
    bitfield->allocate();
 
136
    bitfield->unset_all();
 
137
 
 
138
    m_ptr->hash_checker()->ranges().insert(0, m_ptr->main()->file_list()->size_chunks());
144
139
  }
145
140
 
 
141
  m_ptr->main()->file_list()->update_completed();
 
142
 
146
143
  return m_ptr->hash_checker()->start(tryQuick);
147
144
}
148
145
 
152
149
  if (!m_ptr->hash_checker()->is_checking())
153
150
    return;
154
151
 
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);
 
154
 
157
155
  m_ptr->hash_checker()->clear();
158
 
 
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);
162
156
}
163
157
 
164
158
bool
189
183
  return m_ptr->info()->name();
190
184
}
191
185
 
192
 
const std::string&
 
186
const HashString&
193
187
Download::info_hash() const {
194
 
  if (m_ptr == NULL)
195
 
    throw internal_error("Download::info_hash() m_ptr == NULL.");
196
 
 
197
188
  return m_ptr->info()->hash();
198
189
}
199
190
 
200
 
const std::string&
 
191
const HashString&
 
192
Download::info_hash_obfuscated() const {
 
193
  return m_ptr->info()->hash_obfuscated();
 
194
}
 
195
 
 
196
const HashString&
201
197
Download::local_id() const {
202
 
  if (m_ptr == NULL)
203
 
    throw internal_error("Download::local_id() m_ptr == NULL.");
204
 
 
205
198
  return m_ptr->info()->local_id();
206
199
}
207
200
 
223
216
  return m_ptr->bencode();
224
217
}
225
218
 
226
 
FileList
 
219
FileList*
227
220
Download::file_list() const {
228
 
  return FileList(m_ptr->main()->content()->entry_list());
 
221
  return m_ptr->main()->file_list();
229
222
}
230
223
 
231
224
TrackerList
258
251
}
259
252
 
260
253
Rate*
 
254
Download::mutable_down_rate() {
 
255
  return m_ptr->info()->down_rate();
 
256
}
 
257
 
 
258
Rate*
261
259
Download::up_rate() {
262
260
  return m_ptr->info()->up_rate();
263
261
}
267
265
  return m_ptr->info()->up_rate();
268
266
}
269
267
 
 
268
Rate*
 
269
Download::mutable_up_rate() {
 
270
  return m_ptr->info()->up_rate();
 
271
}
 
272
 
 
273
Rate*
 
274
Download::skip_rate() {
 
275
  return m_ptr->info()->skip_rate();
 
276
}
 
277
 
 
278
const Rate*
 
279
Download::skip_rate() const {
 
280
  return m_ptr->info()->skip_rate();
 
281
}
 
282
 
 
283
Rate*
 
284
Download::mutable_skip_rate() {
 
285
  return m_ptr->info()->skip_rate();
 
286
}
 
287
 
270
288
uint64_t
271
289
Download::bytes_done() const {
272
290
  uint64_t a = 0;
278
296
      if (itr2->is_finished())
279
297
        a += itr2->piece().length();
280
298
  
281
 
  return a + m_ptr->main()->content()->bytes_completed();
282
 
}
283
 
 
284
 
uint64_t
285
 
Download::bytes_total() const {
286
 
  return m_ptr->main()->content()->entry_list()->bytes_size();
287
 
}
288
 
 
289
 
uint64_t
290
 
Download::free_diskspace() const {
291
 
  return m_ptr->main()->content()->entry_list()->free_diskspace();
292
 
}
293
 
 
294
 
uint32_t
295
 
Download::chunks_size() const {
296
 
  return m_ptr->main()->content()->chunk_size();
297
 
}
298
 
 
299
 
uint32_t
300
 
Download::chunks_done() const {
301
 
  return m_ptr->main()->content()->chunks_completed();
302
 
}
303
 
 
304
 
uint32_t 
305
 
Download::chunks_total() const {
306
 
  return m_ptr->main()->content()->chunk_total();
 
299
  return a + m_ptr->main()->file_list()->completed_bytes();
307
300
}
308
301
 
309
302
uint32_t 
321
314
  if (m_ptr->info()->is_open())
322
315
    throw input_error("Download::set_chunks_done(...) Download is open.");
323
316
 
324
 
  m_ptr->main()->content()->bitfield()->set_size_set(chunks);
 
317
  m_ptr->main()->file_list()->mutable_bitfield()->set_size_set(chunks);
325
318
}
326
319
 
327
320
void
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.");
331
324
 
332
 
  Bitfield* bitfield = m_ptr->main()->content()->bitfield();
 
325
  Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
333
326
 
334
327
  bitfield->allocate();
335
328
 
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.");
348
341
 
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.");
351
344
 
352
 
  Bitfield* bitfield = m_ptr->main()->content()->bitfield();
 
345
  Bitfield* bitfield = m_ptr->main()->file_list()->mutable_bitfield();
353
346
 
354
347
  bitfield->allocate();
355
348
  std::memcpy(bitfield->begin(), first, bitfield->size_bytes());
360
353
 
361
354
void
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.");
365
358
 
 
359
  // Unset progress of any files.
 
360
 
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);
368
363
}
369
364
 
370
 
const Bitfield*
371
 
Download::bitfield() const {
372
 
  return m_ptr->main()->content()->bitfield();
373
 
}
374
 
 
375
365
void
376
366
Download::sync_chunks() {
377
367
  m_ptr->main()->chunk_list()->sync_chunks(ChunkList::sync_all | ChunkList::sync_force);
409
399
 
410
400
uint32_t
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();
413
403
}
414
404
 
415
405
uint32_t
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();
418
408
}
419
409
 
420
410
bool
424
414
 
425
415
uint32_t
426
416
Download::uploads_max() const {
427
 
  return m_ptr->main()->choke_manager()->max_unchoked();
 
417
  return m_ptr->main()->upload_choke_manager()->max_unchoked();
428
418
}
429
419
  
430
420
void
449
439
  if (v > (1 << 16))
450
440
    throw input_error("Max uploads must be between 0 and 2^16.");
451
441
 
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();
454
445
}
455
446
 
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))));
493
484
 
494
485
  return itr != m_ptr->main()->connection_list()->end() ? *itr : NULL;
495
486
}