1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2006, Jari Sundell
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// In addition, as a special exception, the copyright holders give
19
// permission to link the code of portions of this program with the
20
// OpenSSL library under certain conditions as described in each
21
// individual source file, and distribute linked combinations
24
// You must obey the GNU General Public License in all respects for
25
// all of the code used other than OpenSSL. If you modify file(s)
26
// with this exception, you may extend this exception to your version
27
// of the file(s), but you are not obligated to do so. If you do not
28
// wish to do so, delete this exception statement from your version.
29
// If you delete this exception statement from all source files in the
30
// program, then also delete it here.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
37
#ifndef LIBTORRENT_BLOCK_H
38
#define LIBTORRENT_BLOCK_H
41
#include <torrent/common.h>
42
#include <torrent/data/block_transfer.h>
46
// If you start adding slots, make sure the rest of the code creates
47
// copies and clears the original variables before calls to erase etc.
49
class LIBTORRENT_EXPORT Block {
51
// Using vectors as they will remain small, thus the cost of erase
52
// should be small. Later we can do faster erase by ignoring the
54
typedef std::vector<BlockTransfer*> transfer_list_type;
55
typedef uint32_t size_type;
57
Block() : m_notStalled(0), m_leader(NULL), m_failedList(NULL) { }
60
bool is_stalled() const { return m_notStalled == 0; }
61
bool is_finished() const { return m_leader != NULL && m_leader->is_finished(); }
62
bool is_transfering() const { return m_leader != NULL && !m_leader->is_finished(); }
64
bool is_peer_queued(const PeerInfo* p) const { return find_queued(p) != NULL; }
65
bool is_peer_transfering(const PeerInfo* p) const { return find_transfer(p) != NULL; }
67
size_type size_all() const { return m_queued.size() + m_transfers.size(); }
68
size_type size_not_stalled() const { return m_notStalled; }
70
BlockList* parent() { return m_parent; }
71
const BlockList* parent() const { return m_parent; }
72
void set_parent(BlockList* p) { m_parent = p; }
74
const Piece& piece() const { return m_piece; }
75
void set_piece(const Piece& p) { m_piece = p; }
77
uint32_t index() const { return m_piece.index(); }
79
const transfer_list_type* queued() const { return &m_queued; }
80
const transfer_list_type* transfers() const { return &m_transfers; }
82
// The leading transfer, whom's data we're currently using.
83
BlockTransfer* leader() { return m_leader; }
84
const BlockTransfer* leader() const { return m_leader; }
86
BlockTransfer* find(const PeerInfo* p);
87
const BlockTransfer* find(const PeerInfo* p) const;
89
BlockTransfer* find_queued(const PeerInfo* p);
90
const BlockTransfer* find_queued(const PeerInfo* p) const;
92
BlockTransfer* find_transfer(const PeerInfo* p);
93
const BlockTransfer* find_transfer(const PeerInfo* p) const;
95
// Internal to libTorrent:
97
BlockTransfer* insert(PeerInfo* peerInfo);
98
void erase(BlockTransfer* transfer);
100
bool transfering(BlockTransfer* transfer);
102
// Return true if all blocks in the chunk is finished.
103
bool completed(BlockTransfer* transfer);
105
void transfer_dissimilar(BlockTransfer* transfer);
107
static void stalled(BlockTransfer* transfer) { if (!transfer->is_valid()) return; transfer->block()->stalled_transfer(transfer); }
108
void stalled_transfer(BlockTransfer* transfer);
110
void change_leader(BlockTransfer* transfer);
111
void failed_leader();
113
BlockFailed* failed_list() { return m_failedList; }
114
void set_failed_list(BlockFailed* f) { m_failedList = f; }
116
static void create_dummy(BlockTransfer* transfer, PeerInfo* peerInfo, const Piece& piece);
118
// If the queued or transfering is already removed from the block it
119
// will just delete the object. Made static so it can be called when
121
static void release(BlockTransfer* transfer);
124
// Block(const Block&);
125
// void operator = (const Block&);
127
void invalidate_transfer(BlockTransfer* transfer) LIBTORRENT_NO_EXPORT;
129
void remove_erased_transfers() LIBTORRENT_NO_EXPORT;
130
void remove_non_leader_transfers() LIBTORRENT_NO_EXPORT;
135
uint32_t m_notStalled;
137
transfer_list_type m_queued;
138
transfer_list_type m_transfers;
140
BlockTransfer* m_leader;
142
BlockFailed* m_failedList;
145
inline BlockTransfer*
146
Block::find(const PeerInfo* p) {
147
BlockTransfer* transfer;
149
if ((transfer = find_queued(p)) != NULL)
152
return find_transfer(p);
155
inline const BlockTransfer*
156
Block::find(const PeerInfo* p) const {
157
const BlockTransfer* transfer;
159
if ((transfer = find_queued(p)) != NULL)
162
return find_transfer(p);