summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-11-05 15:04:17 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-11-05 15:04:17 +0000
commitec642ad294dd8fe6238b3a47309293c1c77beb68 (patch)
tree148f3116687d3f1cc413810fa067ca52d56aa68e /src
parentb8737b0e7c92fb4a5b1c8b6173663381aacca40c (diff)
2006-11-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To divide TorrentMan into 6 classes: BtContext, BtRuntime, PeerStorage, PieceStorage, BtAnnounce and BtProgressInfoFile * src/TrackerWatcherComand.h: Made subclass of BtContextAwareCommand. * src/SeedCheckCommand.cc: Use pieceStorage, btRuntime * src/PeerAbstractCommand.h: Made subclass of BtContextAwareCommand. * src/PeerAbstractCommand.cc: Use btRuntime. * src/BtContextAwareCommand.h: New class. * src/FileEntry.h: Added accessor methods for following variables. (path): Made private. (length): Made private. (offset): Made private. (extracted): Made private. (requested): Made private. (FileEntries): New definition. (FileEntryHandle): New definition. * src/FileEntry.cc: New file. * src/HaveEraseCommand.h: Made subclass of BtContextAwareCommand. * src/HaveEraseCommand.cc: Use btRuntime, pieceStorage. * src/PeerChokeCommand.h: Made subclass of BtContextAwareCommand. * src/PeerChokeCommand.cc: Use btRuntime, peerStorage, pieceStorage. * src/PieceStorage.h: New file. * src/PeerInteractionCommand.h: Use btContext. * src/PeerInteractionCommand.cc: Use pieceStorage, peerStorage, btRuntime. * src/DefaultBtProgressInfoFile.h: New file. * src/DefaultBtProgressInfoFile.cc: New file. * src/File.cc (Util.h): New include. (mkdirs): New function. * src/MultiDiskAdaptor.h (mkdir): New function. * src/PeerListProcessor.h (Peers): Removed. * src/PeerInteraction.h (torrentMan): Removed. (btContext): New variable. (peerStorage): New variable. (pieceStorage): New variable. (btAnnounce): New variable. (getTorrentMan): Removed. (getBtContext): New function. * src/PeerInteraction.cc: Use btContext, peerStorage, pieceStorage, btAnnounce. * src/HandshakeMessage.h (TorrentMan.h): Removed. * src/HandshakeMessage.cc: Use btContext. * src/DefaultBtAnnounce.cc: New file. * src/MultiDiskWriter.cc: Use the accessor methods of FileEntry. * src/DefaultPieceStorage.cc: New file. * src/DefaultBtContext.h: New file. * src/TorrentRequestInfo.cc: Use btContext, pieceStorage. Use the accessor methods of FileEntry. * src/CookieBox.cc: Updated to use Util::slice(). * src/PieceMessage.cc: Use btContext, pieceStorage. * src/common.h (SharedHandle.h): New include. * src/PeerMessage.cc (PeerMessage): Added btContext, peerStorage, pieceStorage. * src/TorrentAutoSaveCommand.h: Made subclass of BtContextAwareCommand. * src/DiskAdaptor.h (topDir): Removed. (getFileEntryFromPath): Changed the return type to FileEntryHandle. (setTopDir): Removed. (getTopDir): Removed. * src/BtContext.h: New file. * src/DefaultPeerStorage.h: New file. * src/PieceMessage.h (TorrentMan.h): Removed. * src/RequestMessage.h (TorrentMan.h): Removed. * src/TorrentDownloadEngine.h (uploadLength): New variable. (btContext): New variable. (btRuntime): New variable. (pieceStorage): New variable. (peerStorage): New variable. (btAnnounce): New variable. (btProgressInfoFile): New variable. (torrentMan): Removed. (setBtContext): New function. * src/TorrentDownloadEngine.cc: Use BtContext, BtRuntime, pieceStorage, peerStorage, btAnnounce, btProgressInfoFile. * src/Piece.h (toString): New function. (Pieces): New type definition. * src/Peer.h (active): New variable. (Peer): Added active. (activate): Set active to true. (deactivate): Set active to false. (isActive): New function. (Peers): New type definition. * src/DirectDiskAdaptor.cc (getFilePath): Use the accessor methods of FileEntry. * src/TorrentConsoleDownloadEngine.h (afterEachIteration): New function. * src/TorrentConsoleDownloadEngine.cc (haltRequested): New variable. (sendStatistics): Use pieceStorage, btRuntime. (afterEachIteration): New function. * src/AnnounceList: AnnounceTier->AnnounceTierHandle. * src/Directry.h (Directory): New function. (DirectoryHandle): New type definition. * src/BtProgressInfoFile.h: New file. * src/RequestMessage.cc: Use pieceStorage. * src/BtRuntime.h: New file. * src/DefaultBtContext.cc: New file. * src/BitfieldMan.h (getCompletedLength): New function(private). (getCompletedLength): New function. (getFilteredCompletedLength): New function. * src/BitfieldMan.h (getCompletedLength): New function(private). (getCompletedLength): New function. (getFilteredCompletedLength): New function. * src/MultiDiskAdaptor.cc (mkdir): New function. (openFile): Call mkdir(). (initAndOpenFile): Call mkdir(). * src/CancelMessage.h (TorrentMan.h): Removed. * src/RejectMessage.h (TorrentMan.h): Removed. * src/DownloadEngineFactory.cc (DefaultPieceStorage.h): New include. (DefaultPeerStorage.h): New include. (DefaultBtAnnounce.h): New include. (DefaultBtProgressInfoFile.h): New include. (newTorrentConsoleEngine): Rewritten. * src/ShareRatioSeedCriteria.h (torrentMan): Removed. (btContext): New variable. (peerStorage): New variable. (btRuntime): New variable. (evaluate): Use btContext, btRuntime, peerStorage. * src/AnnounceTier.h: New file. * src/BtAnnounce.h: New file. * src/BtRegistry.h: New file. * src/PeerInitiateConnectionCommand.h: Added btContext. * src/PeerConnection.h (TorrentMan.h): Removed. * src/PeerMessageFactory.cc: Use btContext, pieceStorage. * src/Util.h (slice): Added an argument. * src/Util.cc (slice): Added an argument to control whether trim is made or not. * src/PeerStorage.h: New file. * src/BtRegistry.cc: New file. * src/TrackerUpdateCommand.h: Made subclass of BtContextAwareCommand. * src/CopyDiskAdaptor.cc: Use the accessor methods of FileEntry. * src/MultiDiskWriter.h: FileEntry -> FileEntryHandle * src/PeerListenCommand.cc: Use btRuntime, peerStorage, btContext. * src/TorrentRequestInfo.h (e): Removed. (showFileEntry): Added an argument. (getDownloadEngine): Return 0. * src/DefaultBtAnnounce.h: New file. * src/TorrentAutoSaveCommand.cc: Use btRuntime, btProgressInfoFile. * src/TrackerWatcherComand.cc: Use btRuntime, btAnnounce, * src/PeerMessageFactory.h (btContext): New variable. (pieceStorage): New variable. * src/TrackerUpdateCommand.cc: Use btRuntime, peerStorage, btContext, btAnnounce. * src/DiskAdaptor.cc (DiskAdaptor): Removed topDir. (~DiskAdaptor): Removed topDir. * src/PeerListenCommand.h: Made subclass of BtContextAwareCommand. * src/SeedCheckCommand.h: Made subclass of BtContextAwareCommand. * src/File.h (mkdirs): New function. * src/DefaultPeerStorage): New file. * src/DownloadEngineFactory.h (newTorrentConsoleEngine): Use btContext. * src/BtContextAwareCommand.cc: New file. * src/PeerInitiateConnectionCommand.cc: Use btRuntime, peerStorage. * src/PeerMessage.h (btContext): New variable. (peerStorage): New variable. (pieceStorage): New variable. (setBtContext): New function. * src/Directry.cc (Directory): New function. (createDir): Do nothing if name.size() == 0. * src/AnnounceList.h (AnnounceTier): Removed. (AnnounceTiers): Removed. * src/DefaultPieceStorage.h: New file. * src/Piece.cc (toString): New function. To fix typo: * src/main.cc (showVersion): Fixed typo. To fix compile warning: * src/DelegatingPeerListProcessor.cc (canHandle): Added "return false".
Diffstat (limited to 'src')
-rw-r--r--src/AnnounceList.cc39
-rw-r--r--src/AnnounceList.h40
-rw-r--r--src/AnnounceTier.h80
-rw-r--r--src/BitfieldMan.cc22
-rw-r--r--src/BitfieldMan.h8
-rw-r--r--src/BtAnnounce.h111
-rw-r--r--src/BtContext.h84
-rw-r--r--src/BtContextAwareCommand.cc48
-rw-r--r--src/BtContextAwareCommand.h60
-rw-r--r--src/BtProgressInfoFile.h59
-rw-r--r--src/BtRegistry.cc130
-rw-r--r--src/BtRegistry.h98
-rw-r--r--src/BtRuntime.h94
-rw-r--r--src/CancelMessage.h1
-rw-r--r--src/CookieBox.cc2
-rw-r--r--src/CopyDiskAdaptor.cc14
-rw-r--r--src/DefaultBtAnnounce.cc246
-rw-r--r--src/DefaultBtAnnounce.h122
-rw-r--r--src/DefaultBtContext.cc237
-rw-r--r--src/DefaultBtContext.h97
-rw-r--r--src/DefaultBtProgressInfoFile.cc172
-rw-r--r--src/DefaultBtProgressInfoFile.h92
-rw-r--r--src/DefaultPeerStorage.cc174
-rw-r--r--src/DefaultPeerStorage.h90
-rw-r--r--src/DefaultPieceStorage.cc433
-rw-r--r--src/DefaultPieceStorage.h158
-rw-r--r--src/DelegatingPeerListProcessor.cc1
-rw-r--r--src/DirectDiskAdaptor.cc2
-rw-r--r--src/Directory.cc5
-rw-r--r--src/Directory.h3
-rw-r--r--src/DiskAdaptor.cc19
-rw-r--r--src/DiskAdaptor.h15
-rw-r--r--src/DownloadEngineFactory.cc77
-rw-r--r--src/DownloadEngineFactory.h4
-rw-r--r--src/File.cc28
-rw-r--r--src/File.h9
-rw-r--r--src/FileEntry.cc64
-rw-r--r--src/FileEntry.h35
-rw-r--r--src/HandshakeMessage.cc2
-rw-r--r--src/HandshakeMessage.h1
-rw-r--r--src/HaveEraseCommand.cc12
-rw-r--r--src/HaveEraseCommand.h12
-rw-r--r--src/Makefile.am19
-rw-r--r--src/Makefile.in70
-rw-r--r--src/MultiDiskAdaptor.cc11
-rw-r--r--src/MultiDiskAdaptor.h1
-rw-r--r--src/MultiDiskWriter.cc20
-rw-r--r--src/MultiDiskWriter.h8
-rw-r--r--src/Peer.h14
-rw-r--r--src/PeerAbstractCommand.cc14
-rw-r--r--src/PeerAbstractCommand.h6
-rw-r--r--src/PeerChokeCommand.cc19
-rw-r--r--src/PeerChokeCommand.h10
-rw-r--r--src/PeerConnection.h1
-rw-r--r--src/PeerInitiateConnectionCommand.cc30
-rw-r--r--src/PeerInitiateConnectionCommand.h7
-rw-r--r--src/PeerInteraction.cc50
-rw-r--r--src/PeerInteraction.h19
-rw-r--r--src/PeerInteractionCommand.cc32
-rw-r--r--src/PeerInteractionCommand.h2
-rw-r--r--src/PeerListProcessor.h2
-rw-r--r--src/PeerListenCommand.cc23
-rw-r--r--src/PeerListenCommand.h9
-rw-r--r--src/PeerMessage.cc6
-rw-r--r--src/PeerMessage.h19
-rw-r--r--src/PeerMessageFactory.cc40
-rw-r--r--src/PeerMessageFactory.h5
-rw-r--r--src/PeerStorage.h128
-rw-r--r--src/Piece.cc5
-rw-r--r--src/Piece.h4
-rw-r--r--src/PieceMessage.cc44
-rw-r--r--src/PieceMessage.h1
-rw-r--r--src/PieceStorage.h157
-rw-r--r--src/RejectMessage.h1
-rw-r--r--src/RequestMessage.cc3
-rw-r--r--src/RequestMessage.h1
-rw-r--r--src/SeedCheckCommand.cc15
-rw-r--r--src/SeedCheckCommand.h14
-rw-r--r--src/ShareRatioSeedCriteria.h23
-rw-r--r--src/TorrentAutoSaveCommand.cc14
-rw-r--r--src/TorrentAutoSaveCommand.h11
-rw-r--r--src/TorrentConsoleDownloadEngine.cc18
-rw-r--r--src/TorrentConsoleDownloadEngine.h2
-rw-r--r--src/TorrentDownloadEngine.cc71
-rw-r--r--src/TorrentDownloadEngine.h19
-rw-r--r--src/TorrentRequestInfo.cc42
-rw-r--r--src/TorrentRequestInfo.h12
-rw-r--r--src/TrackerUpdateCommand.cc34
-rw-r--r--src/TrackerUpdateCommand.h9
-rw-r--r--src/TrackerWatcherCommand.cc29
-rw-r--r--src/TrackerWatcherCommand.h9
-rw-r--r--src/Util.cc16
-rw-r--r--src/Util.h2
-rw-r--r--src/common.h2
-rw-r--r--src/main.cc2
95 files changed, 3693 insertions, 432 deletions
diff --git a/src/AnnounceList.cc b/src/AnnounceList.cc
index 43d0daa7..fbe8025a 100644
--- a/src/AnnounceList.cc
+++ b/src/AnnounceList.cc
@@ -59,7 +59,7 @@ void AnnounceList::reconfigure(const MetaEntry* announceListEntry) {
urls.push_back(data->toString());
}
if(urls.size()) {
- AnnounceTier tier(urls);
+ AnnounceTierHandle tier(new AnnounceTier(urls));
tiers.push_back(tier);
}
}
@@ -70,14 +70,14 @@ void AnnounceList::reconfigure(const MetaEntry* announceListEntry) {
void AnnounceList::reconfigure(const string& url) {
Strings urls;
urls.push_back(url);
- tiers.push_back(AnnounceTier(urls));
+ tiers.push_back(AnnounceTierHandle(new AnnounceTier(urls)));
resetIterator();
}
void AnnounceList::resetIterator() {
currentTier = tiers.begin();
- if(currentTier != tiers.end() && currentTier->urls.size()) {
- currentTracker = currentTier->urls.begin();
+ if(currentTier != tiers.end() && (*currentTier)->urls.size()) {
+ currentTracker = (*currentTier)->urls.begin();
currentTrackerInitialized = true;
} else {
currentTrackerInitialized = false;
@@ -94,31 +94,31 @@ string AnnounceList::getAnnounce() const {
void AnnounceList::announceSuccess() {
if(currentTrackerInitialized) {
- currentTier->nextEvent();
+ (*currentTier)->nextEvent();
string url = *currentTracker;
- currentTier->urls.erase(currentTracker);
- currentTier->urls.push_front(url);
+ (*currentTier)->urls.erase(currentTracker);
+ (*currentTier)->urls.push_front(url);
currentTier = tiers.begin();
- currentTracker = currentTier->urls.begin();
+ currentTracker = (*currentTier)->urls.begin();
}
}
void AnnounceList::announceFailure() {
if(currentTrackerInitialized) {
currentTracker++;
- if(currentTracker == currentTier->urls.end()) {
+ if(currentTracker == (*currentTier)->urls.end()) {
currentTier++;
if(currentTier == tiers.end()) {
currentTier = tiers.begin();
}
- currentTracker = currentTier->urls.begin();
+ currentTracker = (*currentTier)->urls.begin();
}
}
}
AnnounceTier::AnnounceEvent AnnounceList::getEvent() const {
if(currentTrackerInitialized) {
- return currentTier->event;
+ return (*currentTier)->event;
} else {
return AnnounceTier::STARTED;
}
@@ -126,13 +126,13 @@ AnnounceTier::AnnounceEvent AnnounceList::getEvent() const {
void AnnounceList::setEvent(AnnounceTier::AnnounceEvent event) {
if(currentTrackerInitialized) {
- currentTier->event = event;
+ (*currentTier)->event = event;
}
}
string AnnounceList::getEventString() const {
if(currentTrackerInitialized) {
- switch(currentTier->event) {
+ switch((*currentTier)->event) {
case AnnounceTier::STARTED:
case AnnounceTier::STARTED_AFTER_COMPLETION:
return "started";
@@ -150,8 +150,8 @@ string AnnounceList::getEventString() const {
class FindStoppedAllowedTier {
public:
- bool operator()(const AnnounceTier& tier) const {
- switch(tier.event) {
+ bool operator()(const AnnounceTierHandle& tier) const {
+ switch(tier->event) {
case AnnounceTier::DOWNLOADING:
case AnnounceTier::STOPPED:
case AnnounceTier::COMPLETED:
@@ -165,8 +165,8 @@ public:
class FindCompletedAllowedTier {
public:
- bool operator()(const AnnounceTier& tier) const {
- switch(tier.event) {
+ bool operator()(const AnnounceTierHandle& tier) const {
+ switch(tier->event) {
case AnnounceTier::DOWNLOADING:
case AnnounceTier::COMPLETED:
return true;
@@ -187,7 +187,7 @@ int AnnounceList::countCompletedAllowedTier() const {
void AnnounceList::setCurrentTier(const AnnounceTiers::iterator& itr) {
if(itr != tiers.end()) {
currentTier = itr;
- currentTracker = currentTier->urls.begin();
+ currentTracker = (*currentTier)->urls.begin();
}
}
@@ -220,6 +220,7 @@ void AnnounceList::moveToCompletedAllowedTier() {
void AnnounceList::shuffle() {
for(AnnounceTiers::iterator itr = tiers.begin();
itr != tiers.end(); itr++) {
- random_shuffle(itr->urls.begin(), itr->urls.end());
+ Strings& urls = (*itr)->urls;
+ random_shuffle(urls.begin(), urls.end());
}
}
diff --git a/src/AnnounceList.h b/src/AnnounceList.h
index d2ecb3d8..fdd19a49 100644
--- a/src/AnnounceList.h
+++ b/src/AnnounceList.h
@@ -37,45 +37,7 @@
#include "common.h"
#include "MetaEntry.h"
-
-class AnnounceTier {
-public:
- enum AnnounceEvent {
- STARTED,
- STARTED_AFTER_COMPLETION,
- DOWNLOADING,
- STOPPED,
- COMPLETED,
- SEEDING,
- HALTED
- };
-
- AnnounceEvent event;
- Strings urls;
-
- AnnounceTier(const Strings& urls):event(STARTED), urls(urls) {}
-
- void nextEvent() {
- switch(event) {
- case STARTED:
- event = DOWNLOADING;
- break;
- case STARTED_AFTER_COMPLETION:
- event = SEEDING;
- break;
- case STOPPED:
- event = HALTED;
- break;
- case COMPLETED:
- event = SEEDING;
- break;
- default:
- break;
- }
- }
-};
-
-typedef deque<AnnounceTier> AnnounceTiers;
+#include "AnnounceTier.h"
class AnnounceList {
public:
diff --git a/src/AnnounceTier.h b/src/AnnounceTier.h
new file mode 100644
index 00000000..85fdc27b
--- /dev/null
+++ b/src/AnnounceTier.h
@@ -0,0 +1,80 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_ANNOUNCE_TIER_H_
+#define _D_ANNOUNCE_TIER_H_
+
+#include "common.h"
+
+class AnnounceTier {
+public:
+ enum AnnounceEvent {
+ STARTED,
+ STARTED_AFTER_COMPLETION,
+ DOWNLOADING,
+ STOPPED,
+ COMPLETED,
+ SEEDING,
+ HALTED
+ };
+
+ AnnounceEvent event;
+ Strings urls;
+
+ AnnounceTier(const Strings& urls):event(STARTED), urls(urls) {}
+
+ void nextEvent() {
+ switch(event) {
+ case STARTED:
+ event = DOWNLOADING;
+ break;
+ case STARTED_AFTER_COMPLETION:
+ event = SEEDING;
+ break;
+ case STOPPED:
+ event = HALTED;
+ break;
+ case COMPLETED:
+ event = SEEDING;
+ break;
+ default:
+ break;
+ }
+ }
+};
+
+typedef SharedHandle<AnnounceTier> AnnounceTierHandle;
+typedef deque<AnnounceTierHandle> AnnounceTiers;
+
+#endif // _D_ANNOUNCE_TIER_H_
diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc
index c05f2826..736bc5b8 100644
--- a/src/BitfieldMan.cc
+++ b/src/BitfieldMan.cc
@@ -510,13 +510,17 @@ long long int BitfieldMan::getFilteredTotalLength() const {
}
}
-long long int BitfieldMan::getCompletedLength() const {
+long long int BitfieldMan::getCompletedLength(bool useFilter) const {
unsigned char* temp = new unsigned char[bitfieldLength];
- for(int i = 0; i < bitfieldLength; i++) {
- temp[i] = bitfield[i];
- if(filterEnabled) {
- temp[i] &= filterBitfield[i];
+ if(useFilter) {
+ for(int i = 0; i < bitfieldLength; i++) {
+ temp[i] = bitfield[i];
+ if(filterEnabled) {
+ temp[i] &= filterBitfield[i];
+ }
}
+ } else {
+ memcpy(temp, bitfield, bitfieldLength);
}
int completedBlocks = countSetBit(temp, bitfieldLength);
long long int completedLength = 0;
@@ -532,3 +536,11 @@ long long int BitfieldMan::getCompletedLength() const {
delete [] temp;
return completedLength;
}
+
+long long int BitfieldMan::getCompletedLength() const {
+ return getCompletedLength(false);
+}
+
+long long int BitfieldMan::getFilteredCompletedLength() const {
+ return getCompletedLength(true);
+}
diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h
index 2760c382..53758601 100644
--- a/src/BitfieldMan.h
+++ b/src/BitfieldMan.h
@@ -59,6 +59,8 @@ private:
int getStartIndex(int index) const;
int getEndIndex(int index) const;
+
+ long long int getCompletedLength(bool useFilter) const;
public:
BitfieldMan(int blockLength, long long int totalLength);
BitfieldMan(const BitfieldMan& bitfieldMan);
@@ -191,11 +193,15 @@ public:
void enableFilter();
void disableFilter();
bool isFilterEnabled() const;
- long long int getFilteredTotalLength() const;
/**
* affected by filter
*/
+ long long int getFilteredTotalLength() const;
long long int getCompletedLength() const;
+ /**
+ * affected by filter
+ */
+ long long int getFilteredCompletedLength() const;
};
#endif // _D_BITFIELD_MAN_H_
diff --git a/src/BtAnnounce.h b/src/BtAnnounce.h
new file mode 100644
index 00000000..3b9e735f
--- /dev/null
+++ b/src/BtAnnounce.h
@@ -0,0 +1,111 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_ANNOUNCE_H_
+#define _D_BT_ANNOUNCE_H_
+
+#include "common.h"
+
+class BtAnnounce {
+public:
+ virtual ~BtAnnounce() {}
+
+ /**
+ * Returns true if announce is required.
+ * Otherwise returns false.
+ *
+ * There are 4 announce timings:
+ * 1) started: when a download just started.
+ * 2) stopped: when the client quits.
+ * 3) completed: when a download just completed.
+ * 4) When a certain amount of time, aka announce interval, specified by
+ * a tracker, is elapsed.
+ */
+ virtual bool isAnnounceReady() = 0;
+
+ /**
+ * Returns announe URL with all necessary parameters included.
+ */
+ virtual string getAnnounceUrl() = 0;
+
+ /**
+ * Tells that the announce process has just started.
+ */
+ virtual void announceStart() = 0;
+
+ /**
+ * Tells that the announce succeeded.
+ */
+ virtual void announceSuccess() = 0;
+
+ /**
+ * Tells that the announce failed.
+ */
+ virtual void announceFailure() = 0;
+
+ /**
+ * Returns true if all announce attempt failed.
+ */
+ virtual bool isAllAnnounceFailed() = 0;
+
+ /**
+ * Resets announce status.
+ */
+ virtual void resetAnnounce() = 0;
+
+ /**
+ * Processes the repsponse from the tracker.
+ */
+ virtual void processAnnounceResponse(const char* trackerResponse,
+ size_t trackerResponseLength) = 0;
+
+ /**
+ * Returns true if no more announce is needed.
+ */
+ virtual bool noMoreAnnounce() = 0;
+
+ /**
+ * Shuffles the URLs in each announce tier.
+ */
+ virtual void shuffleAnnounce() = 0;
+
+ /**
+ * Returns the peer id of the client.
+ */
+ virtual string getPeerId() = 0;
+};
+
+typedef SharedHandle<BtAnnounce> BtAnnounceHandle;
+
+#endif // _D_BT_ANNOUNCE_H_
diff --git a/src/BtContext.h b/src/BtContext.h
new file mode 100644
index 00000000..ad05c4f8
--- /dev/null
+++ b/src/BtContext.h
@@ -0,0 +1,84 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CONTEXT_H_
+#define _D_BT_CONTEXT_H_
+
+#include "common.h"
+#include "FileEntry.h"
+#include "AnnounceTier.h"
+
+#define INFO_HASH_LENGTH 20
+#define MAX_PEER_ERROR 5
+#define MAX_PEERS 55
+
+typedef deque<AnnounceTierHandle> AnnounceTiers;
+
+class BtContext {
+public:
+ virtual ~BtContext() {}
+
+ enum FILE_MODE {
+ SINGLE,
+ MULTI
+ };
+
+ virtual const unsigned char* getInfoHash() const = 0;
+
+ virtual int getInfoHashLength() const = 0;
+
+ virtual string getInfoHashAsString() const = 0;
+
+ virtual string getPieceHash(int index) const = 0;
+
+ virtual long long int getTotalLength() const = 0;
+
+ virtual FILE_MODE getFileMode() const = 0;
+
+ virtual FileEntries getFileEntries() const = 0;
+
+ virtual AnnounceTiers getAnnounceTiers() const = 0;
+
+ virtual void load(const string& torrentFile) = 0;
+
+ virtual string getName() const = 0;
+
+ virtual int getPieceLength() const = 0;
+
+ virtual int getNumPieces() const = 0;
+};
+
+typedef SharedHandle<BtContext> BtContextHandle;
+
+#endif // _D_BT_CONTEXT_H_
diff --git a/src/BtContextAwareCommand.cc b/src/BtContextAwareCommand.cc
new file mode 100644
index 00000000..b45d6ddc
--- /dev/null
+++ b/src/BtContextAwareCommand.cc
@@ -0,0 +1,48 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "BtContextAwareCommand.h"
+#include "BtRegistry.h"
+
+BtContextAwareCommand::BtContextAwareCommand(int cuid,
+ const BtContextHandle& btContext):
+ Command(cuid),
+ btContext(btContext),
+ btRuntime(BT_RUNTIME(btContext)),
+ pieceStorage(PIECE_STORAGE(btContext)),
+ peerStorage(PEER_STORAGE(btContext)),
+ btAnnounce(BT_ANNOUNCE(btContext)),
+ btProgressInfoFile(BT_PROGRESS_INFO_FILE(btContext)) {}
+
+BtContextAwareCommand::~BtContextAwareCommand() {}
diff --git a/src/BtContextAwareCommand.h b/src/BtContextAwareCommand.h
new file mode 100644
index 00000000..44bbd9b6
--- /dev/null
+++ b/src/BtContextAwareCommand.h
@@ -0,0 +1,60 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_CONTEXT_AWARE_COMMAND_H_
+#define _D_BT_CONTEXT_AWARE_COMMAND_H_
+
+#include "Command.h"
+#include "BtContext.h"
+#include "BtRuntime.h"
+#include "PieceStorage.h"
+#include "PeerStorage.h"
+#include "BtAnnounce.h"
+#include "BtProgressInfoFile.h"
+
+class BtContextAwareCommand : public Command {
+protected:
+ BtContextHandle btContext;
+ BtRuntimeHandle btRuntime;
+ PieceStorageHandle pieceStorage;
+ PeerStorageHandle peerStorage;
+ BtAnnounceHandle btAnnounce;
+ BtProgressInfoFileHandle btProgressInfoFile;
+public:
+ BtContextAwareCommand(int cuid, const BtContextHandle& btContext);
+
+ virtual ~BtContextAwareCommand();
+};
+
+#endif // _D_BT_CONTEXT_AWARE_COMMAND_H_
diff --git a/src/BtProgressInfoFile.h b/src/BtProgressInfoFile.h
new file mode 100644
index 00000000..e4d8f2ff
--- /dev/null
+++ b/src/BtProgressInfoFile.h
@@ -0,0 +1,59 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_PROGRESS_INFO_FILE_H_
+#define _D_BT_PROGRESS_INFO_FILE_H_
+
+#include "common.h"
+
+class BtProgressInfoFile {
+public:
+ virtual ~BtProgressInfoFile() {}
+
+ virtual string getFilename() = 0;
+
+ virtual void setFilename(const string& filename) = 0;
+
+ virtual bool exists() = 0;
+
+ virtual void save() = 0;
+
+ virtual void load() = 0;
+
+ virtual void removeFile() = 0;
+};
+
+typedef SharedHandle<BtProgressInfoFile> BtProgressInfoFileHandle;
+
+#endif // _D_BT_PROGRESS_INFO_FILE_H_
diff --git a/src/BtRegistry.cc b/src/BtRegistry.cc
new file mode 100644
index 00000000..cdd9c6e6
--- /dev/null
+++ b/src/BtRegistry.cc
@@ -0,0 +1,130 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "BtRegistry.h"
+#include "DlAbortEx.h"
+
+PeerStorageMap BtRegistry::peerStorageMap;
+PieceStorageMap BtRegistry::pieceStorageMap;
+BtAnnounceMap BtRegistry::btAnnounceMap;
+BtRuntimeMap BtRegistry::btRuntimeMap;
+BtProgressInfoFileMap BtRegistry::btProgressInfoFileMap;
+
+PeerStorageHandle BtRegistry::getPeerStorage(const string& key) {
+ PeerStorageMap::iterator itr = peerStorageMap.find(key);
+ if(itr == peerStorageMap.end()) {
+ return PeerStorageHandle(0);
+ } else {
+ return itr->second;
+ }
+}
+
+bool BtRegistry::registerPeerStorage(const string& key,
+ const PeerStorageHandle& peerStorage) {
+ PeerStorageMap::value_type p(key, peerStorage);
+ pair<PeerStorageMap::iterator, bool> retval = peerStorageMap.insert(p);
+ return retval.second;
+}
+
+PieceStorageHandle
+BtRegistry::getPieceStorage(const string& key) {
+ PieceStorageMap::iterator itr = pieceStorageMap.find(key);
+ if(itr == pieceStorageMap.end()) {
+ return PieceStorageHandle(0);
+ } else {
+ return itr->second;
+ }
+}
+
+bool
+BtRegistry::registerPieceStorage(const string& key,
+ const PieceStorageHandle& pieceStorage) {
+ PieceStorageMap::value_type p(key, pieceStorage);
+ pair<PieceStorageMap::iterator, bool> retval = pieceStorageMap.insert(p);
+ return retval.second;
+}
+
+BtRuntimeHandle BtRegistry::getBtRuntime(const string& key) {
+ BtRuntimeMap::iterator itr = btRuntimeMap.find(key);
+ if(itr == btRuntimeMap.end()) {
+ return BtRuntimeHandle(0);
+ } else {
+ return itr->second;
+ }
+}
+
+bool
+BtRegistry::registerBtRuntime(const string& key,
+ const BtRuntimeHandle& btRuntime) {
+ BtRuntimeMap::value_type p(key, btRuntime);
+ pair<BtRuntimeMap::iterator, bool> retval =
+ btRuntimeMap.insert(p);
+ return retval.second;
+}
+
+BtAnnounceHandle BtRegistry::getBtAnnounce(const string& key) {
+ BtAnnounceMap::iterator itr = btAnnounceMap.find(key);
+ if(itr == btAnnounceMap.end()) {
+ return BtAnnounceHandle(0);
+ } else {
+ return itr->second;
+ }
+}
+
+bool
+BtRegistry::registerBtAnnounce(const string& key,
+ const BtAnnounceHandle& btAnnounce) {
+ BtAnnounceMap::value_type p(key, btAnnounce);
+ pair<BtAnnounceMap::iterator, bool> retval =
+ btAnnounceMap.insert(p);
+ return retval.second;
+}
+
+BtProgressInfoFileHandle BtRegistry::getBtProgressInfoFile(const string& key) {
+ BtProgressInfoFileMap::iterator itr = btProgressInfoFileMap.find(key);
+ if(itr == btProgressInfoFileMap.end()) {
+ return BtProgressInfoFileHandle(0);
+ } else {
+ return itr->second;
+ }
+}
+
+bool
+BtRegistry::registerBtProgressInfoFile(const string& key,
+ const BtProgressInfoFileHandle& btProgressInfoFile) {
+ BtProgressInfoFileMap::value_type p(key, btProgressInfoFile);
+ pair<BtProgressInfoFileMap::iterator, bool> retval =
+ btProgressInfoFileMap.insert(p);
+ return retval.second;
+}
diff --git a/src/BtRegistry.h b/src/BtRegistry.h
new file mode 100644
index 00000000..f8356a23
--- /dev/null
+++ b/src/BtRegistry.h
@@ -0,0 +1,98 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_REGISTRY_H_
+#define _D_BT_REGISTRY_H_
+
+#include "common.h"
+#include "PeerStorage.h"
+#include "PieceStorage.h"
+#include "BtAnnounce.h"
+#include "BtRuntime.h"
+#include "BtProgressInfoFile.h"
+#include <map>
+
+typedef map<string, PeerStorageHandle> PeerStorageMap;
+typedef map<string, PieceStorageHandle> PieceStorageMap;
+typedef map<string, BtAnnounceHandle> BtAnnounceMap;
+typedef map<string, BtRuntimeHandle> BtRuntimeMap;
+typedef map<string, BtProgressInfoFileHandle> BtProgressInfoFileMap;
+
+class BtRegistry {
+private:
+ BtRegistry() {}
+
+ static PeerStorageMap peerStorageMap;
+ static PieceStorageMap pieceStorageMap;
+ static BtAnnounceMap btAnnounceMap;
+ static BtRuntimeMap btRuntimeMap;
+ static BtProgressInfoFileMap btProgressInfoFileMap;
+public:
+ static PeerStorageHandle getPeerStorage(const string& key);
+ static bool registerPeerStorage(const string& key,
+ const PeerStorageHandle& peer);
+
+ static PieceStorageHandle getPieceStorage(const string& key);
+ static bool registerPieceStorage(const string& key,
+ const PieceStorageHandle& pieceStorage);
+
+ static BtRuntimeHandle getBtRuntime(const string& key);
+ static bool registerBtRuntime(const string& key,
+ const BtRuntimeHandle& btRuntime);
+
+ static BtAnnounceHandle getBtAnnounce(const string& key);
+ static bool registerBtAnnounce(const string& key,
+ const BtAnnounceHandle& btAnnounce);
+
+ static BtProgressInfoFileHandle getBtProgressInfoFile(const string& key);
+ static bool registerBtProgressInfoFile(const string& key,
+ const BtProgressInfoFileHandle& btProgressInfoFile);
+};
+
+#define PEER_STORAGE(btContext) \
+BtRegistry::getPeerStorage(btContext->getInfoHashAsString())
+
+#define PIECE_STORAGE(btContext) \
+BtRegistry::getPieceStorage(btContext->getInfoHashAsString())
+
+#define BT_ANNOUNCE(btContext) \
+BtRegistry::getBtAnnounce(btContext->getInfoHashAsString())
+
+#define BT_RUNTIME(btContext) \
+BtRegistry::getBtRuntime(btContext->getInfoHashAsString())
+
+#define BT_PROGRESS_INFO_FILE(btContext) \
+BtRegistry::getBtProgressInfoFile(btContext->getInfoHashAsString())
+
+#endif // _D_BT_REGISTRY_H_
diff --git a/src/BtRuntime.h b/src/BtRuntime.h
new file mode 100644
index 00000000..911fa6d3
--- /dev/null
+++ b/src/BtRuntime.h
@@ -0,0 +1,94 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_BT_RUNTIME_H_
+#define _D_BT_RUNTIME_H_
+
+#include "common.h"
+#include "SharedHandle.h"
+
+#define MIN_PEERS 15
+
+class BtRuntime {
+private:
+ long long int uploadLengthAtStartup;
+ int port;
+ bool halt;
+ int connections;
+ int cuidCounter;
+public:
+ BtRuntime():
+ uploadLengthAtStartup(0),
+ port(0),
+ halt(false),
+ connections(0),
+ cuidCounter(0) {}
+ ~BtRuntime() {}
+
+ long long int getUploadLengthAtStartup() const {
+ return uploadLengthAtStartup;
+ }
+
+ void setUploadLengthAtStartup(long long int length) {
+ this->uploadLengthAtStartup = length;
+ }
+
+ void setListenPort(int port) {
+ this->port = port;
+ }
+
+ int getListenPort() const { return port; }
+
+ bool isHalt() const { return halt; }
+
+ void setHalt(bool halt) {
+ this->halt = halt;
+ }
+
+ int getConnections() const { return connections; }
+
+ void increaseConnections() { connections++; }
+
+ void decreaseConnections() { connections--; }
+
+ bool lessThanMinPeer() const { return connections < MIN_PEERS; }
+
+ bool lessThanEqMinPeer() const { return connections <= MIN_PEERS; }
+
+ int getNewCuid() { return ++cuidCounter; }
+};
+
+typedef SharedHandle<BtRuntime> BtRuntimeHandle;
+
+#endif // _D_BT_RUNTIME_H_
diff --git a/src/CancelMessage.h b/src/CancelMessage.h
index 1511d82a..b1a15281 100644
--- a/src/CancelMessage.h
+++ b/src/CancelMessage.h
@@ -36,7 +36,6 @@
#define _D_CANCEL_MESSAGE_H_
#include "SimplePeerMessage.h"
-#include "TorrentMan.h"
class CancelMessage : public SimplePeerMessage {
private:
diff --git a/src/CookieBox.cc b/src/CookieBox.cc
index 5ec2abf3..42010121 100644
--- a/src/CookieBox.cc
+++ b/src/CookieBox.cc
@@ -68,7 +68,7 @@ void CookieBox::setField(Cookie& cookie, const string& name, const string& value
void CookieBox::parse(Cookie& cookie, const string& cookieStr) const {
cookie.clear();
Strings terms;
- Util::slice(terms, cookieStr, ';');
+ Util::slice(terms, cookieStr, ';', true);
for(Strings::iterator itr = terms.begin(); itr != terms.end(); itr++) {
pair<string, string> nv;
Util::split(nv, *itr, '=');
diff --git a/src/CopyDiskAdaptor.cc b/src/CopyDiskAdaptor.cc
index 5318d5c4..c39d8f8a 100644
--- a/src/CopyDiskAdaptor.cc
+++ b/src/CopyDiskAdaptor.cc
@@ -46,19 +46,17 @@ void CopyDiskAdaptor::onDownloadComplete() {
}
void CopyDiskAdaptor::fixFilename() {
- if(topDir != NULL) {
- topDir->createDir(storeDir, true);
- }
long long int offset = 0;
for(FileEntries::iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
- if(!itr->extracted && itr->requested) {
- string dest = storeDir+"/"+itr->path;
+ if(!(*itr)->isExtracted() && (*itr)->isRequested()) {
+ (*itr)->setupDir(storeDir);
+ string dest = storeDir+"/"+(*itr)->getPath();
logger->info("writing file %s", dest.c_str());
- Util::rangedFileCopy(dest, getFilePath(), offset, itr->length);
- itr->extracted = true;
+ Util::rangedFileCopy(dest, getFilePath(), offset, (*itr)->getLength());
+ (*itr)->setExtracted(true);
}
- offset += itr->length;
+ offset += (*itr)->getLength();
}
}
diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc
new file mode 100644
index 00000000..04e069eb
--- /dev/null
+++ b/src/DefaultBtAnnounce.cc
@@ -0,0 +1,246 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "DefaultBtAnnounce.h"
+#include "BtRegistry.h"
+#include "LogFactory.h"
+#include "MetaFileUtil.h"
+#include "Dictionary.h"
+#include "List.h"
+#include "Data.h"
+#include "DelegatingPeerListProcessor.h"
+#include "Util.h"
+#include "prefs.h"
+#include "DlAbortEx.h"
+#include "message.h"
+
+DefaultBtAnnounce::DefaultBtAnnounce(BtContextHandle btContext,
+ const Option* option):
+ btContext(btContext),
+ trackers(0),
+ interval(DEFAULT_ANNOUNCE_INTERVAL),
+ minInterval(DEFAULT_ANNOUNCE_INTERVAL),
+ complete(0),
+ incomplete(0),
+ announceList(btContext->getAnnounceTiers()),
+ trackerNumTry(0),
+ option(option),
+ btRuntime(BT_RUNTIME(btContext)),
+ pieceStorage(PIECE_STORAGE(btContext)),
+ peerStorage(PEER_STORAGE(btContext))
+{
+ prevAnnounceTime.setTimeInSec(0);
+ key = generateKey();
+ peerId = generatePeerId();
+ logger = LogFactory::getInstance();
+}
+
+DefaultBtAnnounce::~DefaultBtAnnounce() {
+}
+
+string DefaultBtAnnounce::generateKey() const {
+ return Util::randomAlpha(8);
+}
+
+string DefaultBtAnnounce::generatePeerId() const {
+ string peerId = "-aria2-";
+ peerId += Util::randomAlpha(20-peerId.size());
+ return peerId;
+}
+
+bool DefaultBtAnnounce::isDefaultAnnounceReady() {
+ return (trackers == 0 && prevAnnounceTime.elapsed(minInterval));
+}
+
+bool DefaultBtAnnounce::isStoppedAnnounceReady() {
+ return (trackers == 0 &&
+ btRuntime->isHalt() &&
+ announceList.countStoppedAllowedTier());
+}
+
+bool DefaultBtAnnounce::isCompletedAnnounceReady() {
+ return (trackers == 0 &&
+ pieceStorage->downloadFinished() &&
+ announceList.countCompletedAllowedTier());
+}
+
+bool DefaultBtAnnounce::isAnnounceReady() {
+ return
+ isStoppedAnnounceReady() ||
+ isCompletedAnnounceReady() ||
+ isDefaultAnnounceReady();
+}
+
+string DefaultBtAnnounce::getAnnounceUrl() {
+ if(isStoppedAnnounceReady()) {
+ announceList.moveToStoppedAllowedTier();
+ announceList.setEvent(AnnounceTier::STOPPED);
+ } else if(isCompletedAnnounceReady()) {
+ announceList.moveToCompletedAllowedTier();
+ announceList.setEvent(AnnounceTier::COMPLETED);
+ } else if(isDefaultAnnounceReady()) {
+ // If download completed before "started" event is sent to a tracker,
+ // we change the event to something else to prevent us from
+ // sending "completed" event.
+ if(pieceStorage->downloadFinished() &&
+ announceList.getEvent() == AnnounceTier::STARTED) {
+ announceList.setEvent(AnnounceTier::STARTED_AFTER_COMPLETION);
+ }
+ }
+ int numWant = 50;
+ if(!btRuntime->lessThanEqMinPeer() ||
+ btRuntime->isHalt()) {
+ numWant = 0;
+ }
+ TransferStat stat = peerStorage->calculateStat();
+ long long int left = pieceStorage->getTotalLength()-pieceStorage->getCompletedLength();
+ if(left < 0) {
+ left = 0;
+ }
+ string url = announceList.getAnnounce()+"?"+
+ "info_hash="+Util::torrentUrlencode(btContext->getInfoHash(),
+ btContext->getInfoHashLength())+"&"+
+ "peer_id="+peerId+"&"+
+ "port="+Util::itos(btRuntime->getListenPort())+"&"+
+ "uploaded="+Util::llitos(stat.getSessionUploadLength())+"&"+
+ "downloaded="+Util::llitos(stat.getSessionDownloadLength())+"&"+
+ "left="+Util::llitos(left)+"&"+
+ "compact=1"+"&"+
+ "key="+key+"&"+
+ "numwant="+Util::itos(numWant)+"&"+
+ "no_peer_id=1";
+ string event = announceList.getEventString();
+ if(!event.empty()) {
+ url += string("&")+"event="+event;
+ }
+ if(!trackerId.empty()) {
+ url += string("&")+"trackerid="+Util::torrentUrlencode((const unsigned char*)trackerId.c_str(),
+ trackerId.size());
+ }
+ return url;
+}
+
+void DefaultBtAnnounce::announceStart() {
+ trackers++;
+}
+
+void DefaultBtAnnounce::announceSuccess() {
+ trackers = 0;
+ announceList.announceSuccess();
+}
+
+void DefaultBtAnnounce::announceFailure() {
+ trackers = 0;
+ trackerNumTry++;
+ announceList.announceFailure();
+}
+
+bool DefaultBtAnnounce::isAllAnnounceFailed() {
+ return
+ trackerNumTry >= option->getAsInt(PREF_TRACKER_MAX_TRIES);
+}
+
+void DefaultBtAnnounce::resetAnnounce() {
+ prevAnnounceTime.reset();
+ trackerNumTry = 0;
+}
+
+void
+DefaultBtAnnounce::processAnnounceResponse(const char* trackerResponse,
+ size_t trackerResponseLength)
+{
+ SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse,
+ trackerResponseLength));
+ Dictionary* response = (Dictionary*)entry.get();
+ Data* failureReasonData = (Data*)response->get("failure reason");
+ if(failureReasonData) {
+ throw new DlAbortEx("Tracker returned failure reason: %s",
+ failureReasonData->toString().c_str());
+ }
+ Data* warningMessageData = (Data*)response->get("warning message");
+ if(warningMessageData) {
+ logger->warn(MSG_TRACKER_WARNING_MESSAGE,
+ warningMessageData->toString().c_str());
+ }
+ Data* trackerIdData = (Data*)response->get("tracker id");
+ if(trackerIdData) {
+ trackerId = trackerIdData->toString();
+ logger->debug("Tracker ID:%s", trackerId.c_str());
+ }
+ Data* intervalData = (Data*)response->get("interval");
+ if(intervalData) {
+ interval = intervalData->toInt();
+ logger->debug("Interval:%d", interval);
+ }
+ Data* minIntervalData = (Data*)response->get("min interval");
+ if(minIntervalData) {
+ minInterval = minIntervalData->toInt();
+ logger->debug("Min interval:%d", minInterval);
+ }
+ if(minInterval > interval) {
+ minInterval = interval;
+ }
+ Data* completeData = (Data*)response->get("complete");
+ if(completeData) {
+ complete = completeData->toInt();
+ logger->debug("Complete:%d", complete);
+ }
+ Data* incompleteData = (Data*)response->get("incomplete");
+ if(incompleteData) {
+ incomplete = incompleteData->toInt();
+ logger->debug("Incomplete:%d", incomplete);
+ }
+ const MetaEntry* peersEntry = response->get("peers");
+ if(peersEntry &&
+ !btRuntime->isHalt() &&
+ btRuntime->lessThanMinPeer()) {
+ DelegatingPeerListProcessor proc(btContext->getPieceLength(),
+ btContext->getTotalLength());
+ Peers peers = proc.extractPeer(peersEntry);
+ peerStorage->addPeer(peers);
+ }
+ if(!peersEntry) {
+ logger->info("No peer list received.");
+ }
+}
+
+bool DefaultBtAnnounce::noMoreAnnounce() {
+ return (trackers == 0 &&
+ btRuntime->isHalt() &&
+ !announceList.countStoppedAllowedTier());
+}
+
+void DefaultBtAnnounce::shuffleAnnounce() {
+ announceList.shuffle();
+}
diff --git a/src/DefaultBtAnnounce.h b/src/DefaultBtAnnounce.h
new file mode 100644
index 00000000..f54c1ac9
--- /dev/null
+++ b/src/DefaultBtAnnounce.h
@@ -0,0 +1,122 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_ANNOUNCE_H_
+#define _D_DEFAULT_BT_ANNOUNCE_H_
+
+#include "BtAnnounce.h"
+#include "BtContext.h"
+#include "TimeA2.h"
+#include "AnnounceList.h"
+#include "Option.h"
+#include "Logger.h"
+#include "BtRuntime.h"
+#include "PieceStorage.h"
+#include "PeerStorage.h"
+
+#define DEFAULT_ANNOUNCE_INTERVAL 1800
+
+class DefaultBtAnnounce : public BtAnnounce {
+private:
+ BtContextHandle btContext;
+ int trackers;
+ Time prevAnnounceTime;
+ int interval;
+ int minInterval;
+ int complete;
+ int incomplete;
+ AnnounceList announceList;
+ string trackerId;
+ string key;
+ int trackerNumTry;
+ string peerId;
+ const Option* option;
+ Logger* logger;
+ BtRuntimeHandle btRuntime;
+ PieceStorageHandle pieceStorage;
+ PeerStorageHandle peerStorage;
+public:
+ DefaultBtAnnounce(BtContextHandle btContext, const Option* option);
+ virtual ~DefaultBtAnnounce();
+
+ void setBtRuntime(const BtRuntimeHandle& btRuntime) {
+ this->btRuntime = btRuntime;
+ }
+ BtRuntimeHandle getBtRuntime() const { return btRuntime; }
+
+ void setPieceStorage(const PieceStorageHandle& pieceStorage) {
+ this->pieceStorage = pieceStorage;
+ }
+ PieceStorageHandle getPieceStorage() const { return pieceStorage; }
+
+ void setPeerStorage(const PeerStorageHandle& peerStorage) {
+ this->peerStorage = peerStorage;
+ }
+ PeerStorageHandle getPeerStorage() const { return peerStorage; }
+
+ bool isDefaultAnnounceReady();
+
+ bool isStoppedAnnounceReady();
+
+ bool isCompletedAnnounceReady();
+
+ virtual bool isAnnounceReady();
+
+ virtual string getAnnounceUrl();
+
+ virtual void announceStart();
+
+ virtual void announceSuccess();
+
+ virtual void announceFailure();
+
+ virtual bool isAllAnnounceFailed();
+
+ virtual void resetAnnounce();
+
+ virtual void processAnnounceResponse(const char* trackerResponse,
+ size_t trackerResponseLength);
+
+ virtual bool noMoreAnnounce();
+
+ virtual void shuffleAnnounce();
+
+ string generateKey() const;
+
+ string generatePeerId() const;
+
+ virtual string getPeerId() { return peerId; }
+};
+
+#endif // _D_DEFAULT_BT_ANNOUNCE_H_
diff --git a/src/DefaultBtContext.cc b/src/DefaultBtContext.cc
new file mode 100644
index 00000000..1acf5fc5
--- /dev/null
+++ b/src/DefaultBtContext.cc
@@ -0,0 +1,237 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "DefaultBtContext.h"
+#include "MetaFileUtil.h"
+#include "Dictionary.h"
+#include "List.h"
+#include "Data.h"
+#include "DlAbortEx.h"
+#include "ShaVisitor.h"
+#include "Util.h"
+
+DefaultBtContext::DefaultBtContext() {}
+
+DefaultBtContext::~DefaultBtContext() {}
+
+const unsigned char* DefaultBtContext::getInfoHash() const {
+ return infoHash;
+}
+
+int DefaultBtContext::getInfoHashLength() const {
+ return INFO_HASH_LENGTH;
+}
+
+string DefaultBtContext::getInfoHashAsString() const {
+ return infoHashString;
+}
+
+void DefaultBtContext::clear() {
+ memset(infoHash, 0, INFO_HASH_LENGTH);
+ infoHashString = "";
+ pieceHashes.clear();
+ fileEntries.clear();
+ totalLength = 0;
+ pieceLength = 0;
+ fileMode = BtContext::SINGLE;
+ numPieces = 0;
+ name = "";
+ announceTiers.clear();
+}
+
+void DefaultBtContext::extractPieceHash(const unsigned char* hashData,
+ int hashDataLength,
+ int hashLength) {
+ assert(hashDataLength > 0);
+ assert(hashLength > 0);
+ int numPieces = hashDataLength/hashLength;
+ assert(numPieces > 0);
+
+ for(int i = 0; i < numPieces; i++) {
+ pieceHashes.push_back(Util::toHex(&hashData[i*hashLength],
+ hashLength));
+ }
+}
+
+void DefaultBtContext::extractFileEntries(Dictionary* infoDic,
+ const string& defaultName) {
+ // TODO use dynamic_cast
+ Data* nameData = (Data*)infoDic->get("name");
+ if(nameData) {
+ name = nameData->toString();
+ } else {
+ char* basec = strdup(defaultName.c_str());
+ name = string(basename(basec))+".file";
+ free(basec);
+ }
+ // TODO use dynamic_cast
+ List* files = (List*)infoDic->get("files");
+ if(files) {
+ long long int length = 0;
+ long long int offset = 0;
+ // multi-file mode
+ fileMode = BtContext::MULTI;
+ const MetaList& metaList = files->getList();
+ for(MetaList::const_iterator itr = metaList.begin();
+ itr != metaList.end(); itr++) {
+ Dictionary* fileDic = (Dictionary*)(*itr);
+ // TODO use dynamic_cast
+ Data* lengthData = (Data*)fileDic->get("length");
+ length += lengthData->toLLInt();
+ // TODO use dynamic_cast
+ List* pathList = (List*)fileDic->get("path");
+ const MetaList& paths = pathList->getList();
+ string path;
+ for(int i = 0; i < (int)paths.size()-1; i++) {
+ Data* subpath = (Data*)paths.at(i);
+ path += subpath->toString()+"/";
+ }
+ // TODO use dynamic_cast
+ Data* lastPath = (Data*)paths.back();
+ path += lastPath->toString();
+
+ FileEntryHandle fileEntry(new FileEntry(path,
+ lengthData->toLLInt(),
+ offset));
+ fileEntries.push_back(fileEntry);
+ offset += fileEntry->getLength();
+ }
+ totalLength = length;
+ } else {
+ // single-file mode;
+ fileMode = BtContext::SINGLE;
+ Data* length = (Data*)infoDic->get("length");
+ totalLength = length->toLLInt();
+ FileEntryHandle fileEntry(new FileEntry(name, totalLength, 0));
+ fileEntries.push_back(fileEntry);
+ }
+}
+
+void DefaultBtContext::extractAnnounce(Data* announceData) {
+ Strings urls;
+ urls.push_back(announceData->toString());
+ announceTiers.push_back(AnnounceTierHandle(new AnnounceTier(urls)));
+}
+
+void DefaultBtContext::extractAnnounceList(List* announceListData) {
+ for(MetaList::const_iterator itr = announceListData->getList().begin();
+ itr != announceListData->getList().end(); itr++) {
+ const List* elem = (List*)*itr;
+ Strings urls;
+ for(MetaList::const_iterator elemItr = elem->getList().begin();
+ elemItr != elem->getList().end(); elemItr++) {
+ const Data* data = (Data*)*elemItr;
+ urls.push_back(data->toString());
+ }
+ if(urls.size()) {
+ AnnounceTierHandle tier(new AnnounceTier(urls));
+ announceTiers.push_back(tier);
+ }
+ }
+}
+
+void DefaultBtContext::load(const string& torrentFile) {
+ clear();
+ MetaEntry* rootEntry = MetaFileUtil::parseMetaFile(torrentFile);
+ if(!dynamic_cast<Dictionary*>(rootEntry)) {
+ throw new DlAbortEx("torrent file does not contain a root dictionary .");
+ }
+ SharedHandle<Dictionary> rootDic =
+ SharedHandle<Dictionary>((Dictionary*)rootEntry);
+ Dictionary* infoDic = (Dictionary*)rootDic->get("info");
+ // retrieve infoHash
+ ShaVisitor v;
+ infoDic->accept(&v);
+ int len;
+ v.getHash(infoHash, len);
+ infoHashString = Util::toHex(infoHash, INFO_HASH_LENGTH);
+ // calculate the number of pieces
+ Data* pieceHashData = (Data*)infoDic->get("pieces");
+ numPieces = pieceHashData->getLen()/PIECE_HASH_LENGTH;
+ // retrieve piece length
+ Data* pieceLengthData = (Data*)infoDic->get("piece length");
+ pieceLength = pieceLengthData->toInt();
+ // retrieve piece hashes
+ extractPieceHash((unsigned char*)pieceHashData->getData(),
+ pieceHashData->getLen(),
+ PIECE_HASH_LENGTH);
+ // retrieve file entries
+ extractFileEntries(infoDic, torrentFile);
+ // retrieve announce
+ Data* announceData = (Data*)rootDic->get("announce");
+ List* announceListData = (List*)rootDic->get("announce-list");
+ if(announceListData) {
+ extractAnnounceList(announceListData);
+ } else if(announceData) {
+ extractAnnounce(announceData);
+ }
+ if(!announceTiers.size()) {
+ throw new DlAbortEx("No announce URL found.");
+ }
+}
+
+string DefaultBtContext::getPieceHash(int index) const {
+ if(index < 0 || numPieces <= index) {
+ return "";
+ }
+ return pieceHashes.at(index);
+}
+
+long long int DefaultBtContext::getTotalLength() const {
+ return totalLength;
+}
+
+BtContext::FILE_MODE DefaultBtContext::getFileMode() const {
+ return fileMode;
+}
+
+FileEntries DefaultBtContext::getFileEntries() const {
+ return fileEntries;
+}
+
+AnnounceTiers DefaultBtContext::getAnnounceTiers() const {
+ return announceTiers;
+}
+
+string DefaultBtContext::getName() const {
+ return name;
+}
+
+int DefaultBtContext::getPieceLength() const {
+ return pieceLength;
+}
+
+int DefaultBtContext::getNumPieces() const {
+ return numPieces;
+}
diff --git a/src/DefaultBtContext.h b/src/DefaultBtContext.h
new file mode 100644
index 00000000..74bae247
--- /dev/null
+++ b/src/DefaultBtContext.h
@@ -0,0 +1,97 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_CONTEXT_H_
+#define _D_DEFAULT_BT_CONTEXT_H_
+
+#include "BtContext.h"
+#include "Dictionary.h"
+#include "Data.h"
+#include "List.h"
+#define INFO_HASH_LENGTH 20
+#define PIECE_HASH_LENGTH 20
+
+typedef Strings PieceHashes;
+
+class DefaultBtContext : public BtContext {
+private:
+ unsigned char infoHash[INFO_HASH_LENGTH];
+ string infoHashString;
+ PieceHashes pieceHashes;
+ FileEntries fileEntries;
+ FILE_MODE fileMode;
+ long long int totalLength;
+ int pieceLength;
+ string name;
+ int numPieces;
+ AnnounceTiers announceTiers;
+
+ void clear();
+ void extractPieceHash(const unsigned char* hashData,
+ int hashDataLength,
+ int hashLength);
+ void extractFileEntries(Dictionary* infoDic,
+ const string& defaultName);
+ void extractAnnounce(Data* announceData);
+ void extractAnnounceList(List* announceListData);
+ public:
+ DefaultBtContext();
+ virtual ~DefaultBtContext();
+
+ virtual const unsigned char* getInfoHash() const;
+
+ virtual int getInfoHashLength() const;
+
+ virtual string getInfoHashAsString() const;
+
+ virtual string getPieceHash(int index) const;
+
+ virtual long long int getTotalLength() const;
+
+ virtual FILE_MODE getFileMode() const;
+
+ virtual FileEntries getFileEntries() const;
+
+ virtual AnnounceTiers getAnnounceTiers() const;
+
+ virtual void load(const string& torrentFile);
+
+ virtual string getName() const;
+
+ virtual int getPieceLength() const;
+
+ virtual int getNumPieces() const;
+};
+
+#endif // _D_DEFAULT_BT_CONTEXT_H_
diff --git a/src/DefaultBtProgressInfoFile.cc b/src/DefaultBtProgressInfoFile.cc
new file mode 100644
index 00000000..a524a589
--- /dev/null
+++ b/src/DefaultBtProgressInfoFile.cc
@@ -0,0 +1,172 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "DefaultBtProgressInfoFile.h"
+#include "BtRegistry.h"
+#include "LogFactory.h"
+#include "prefs.h"
+#include "DlAbortEx.h"
+#include "message.h"
+#include "File.h"
+#include "Util.h"
+#include <errno.h>
+
+DefaultBtProgressInfoFile::DefaultBtProgressInfoFile(const BtContextHandle& btContext,
+ const Option* option):
+ btContext(btContext),
+ option(option),
+ pieceStorage(PIECE_STORAGE(btContext)),
+ btRuntime(BT_RUNTIME(btContext)),
+ peerStorage(PEER_STORAGE(btContext))
+{
+ logger = LogFactory::getInstance();
+ string storeDir = option->get(PREF_DIR);
+ filename = storeDir+"/"+btContext->getName()+".aria2";
+}
+
+DefaultBtProgressInfoFile::~DefaultBtProgressInfoFile() {}
+
+void DefaultBtProgressInfoFile::save() {
+ logger->info(MSG_SAVING_SEGMENT_FILE, filename.c_str());
+ FILE* file = openFile(filename, "w");
+ try {
+ if(fwrite(btContext->getInfoHash(),
+ btContext->getInfoHashLength(), 1, file) < 1) {
+ throw string("writeError:info hash");
+ }
+ if(fwrite(pieceStorage->getBitfield(),
+ pieceStorage->getBitfieldLength(), 1, file) < 1) {
+ throw string("writeError:bitfield");
+ }
+ TransferStat stat = peerStorage->calculateStat();
+ long long int allTimeDownloadLength = pieceStorage->getCompletedLength();
+ if(fwrite(&allTimeDownloadLength,
+ sizeof(allTimeDownloadLength), 1, file) < 1) {
+ throw string("writeError:download length");
+ }
+ long long int allTimeUploadLength =
+ btRuntime->getUploadLengthAtStartup()+
+ stat.getSessionUploadLength();
+ if(fwrite(&allTimeUploadLength,
+ sizeof(allTimeUploadLength), 1, file) < 1) {
+ throw string("writeError:upload length");
+ }
+ fclose(file);
+ logger->info(MSG_SAVED_SEGMENT_FILE);
+ } catch(string ex) {
+ fclose(file);
+ throw new DlAbortEx(EX_SEGMENT_FILE_WRITE,
+ filename.c_str(), strerror(errno));
+ }
+}
+
+void DefaultBtProgressInfoFile::load() {
+ logger->info(MSG_LOADING_SEGMENT_FILE, filename.c_str());
+ FILE* file = openFile(filename, "r+");
+ unsigned char* savedInfoHash = 0;
+ unsigned char* savedBitfield = 0;
+ try {
+ savedInfoHash = new unsigned char[btContext->getInfoHashLength()];
+ savedBitfield = new unsigned char[pieceStorage->getBitfieldLength()];
+ if(fread(savedInfoHash, btContext->getInfoHashLength(), 1, file) < 1) {
+ throw string("readError");
+ }
+ if(Util::toHex(savedInfoHash, btContext->getInfoHashLength()) !=
+ btContext->getInfoHashAsString()) {
+ throw new DlAbortEx("Incorrect infoHash.");
+ }
+ if(fread(savedBitfield, pieceStorage->getBitfieldLength(), 1, file) < 1) {
+ throw string("readError");
+ }
+ pieceStorage->setBitfield(savedBitfield,
+ pieceStorage->getBitfieldLength());
+ // allTimeDownloadLength exists for only a compatibility reason.
+ long long int allTimeDownloadLength;
+ if(fread(&allTimeDownloadLength,
+ sizeof(allTimeDownloadLength), 1, file) < 1) {
+ throw string("readError");
+ }
+ long long int allTimeUploadLength;
+ if(fread(&allTimeUploadLength,
+ sizeof(allTimeUploadLength), 1, file) < 1) {
+ throw string("readError");
+ }
+ btRuntime->setUploadLengthAtStartup(allTimeUploadLength);
+ delete [] savedBitfield;
+ savedBitfield = 0;
+ delete [] savedInfoHash;
+ savedInfoHash = 0;
+ fclose(file);
+ } catch(string ex) {
+ if(savedBitfield) {
+ delete [] savedBitfield;
+ }
+ if(savedInfoHash) {
+ delete [] savedInfoHash;
+ }
+ fclose(file);
+ throw new DlAbortEx(EX_SEGMENT_FILE_READ,
+ filename.c_str(), strerror(errno));
+ }
+ logger->info(MSG_LOADED_SEGMENT_FILE);
+}
+
+void DefaultBtProgressInfoFile::removeFile() {
+ if(exists()) {
+ File f(filename);
+ f.remove();
+ }
+}
+
+FILE* DefaultBtProgressInfoFile::openFile(const string& filename,
+ const string& mode) const
+{
+ FILE* file = fopen(filename.c_str(), mode.c_str());
+ if(!file) {
+ throw new DlAbortEx(EX_SEGMENT_FILE_OPEN,
+ filename.c_str(), strerror(errno));
+ }
+ return file;
+}
+
+bool DefaultBtProgressInfoFile::exists() {
+ File f(filename);
+ if(f.isFile()) {
+ logger->info(MSG_SEGMENT_FILE_EXISTS, filename.c_str());
+ return true;
+ } else {
+ logger->info(MSG_SEGMENT_FILE_DOES_NOT_EXIST, filename.c_str());
+ return false;
+ }
+}
diff --git a/src/DefaultBtProgressInfoFile.h b/src/DefaultBtProgressInfoFile.h
new file mode 100644
index 00000000..201900dd
--- /dev/null
+++ b/src/DefaultBtProgressInfoFile.h
@@ -0,0 +1,92 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_BT_PROGRESS_INFO_FILE_H_
+#define _D_DEFAULT_BT_PROGRESS_INFO_FILE_H_
+
+#include "BtProgressInfoFile.h"
+#include "BtContext.h"
+#include "PieceStorage.h"
+#include "BtRuntime.h"
+#include "PeerStorage.h"
+#include "Logger.h"
+#include "Option.h"
+
+class DefaultBtProgressInfoFile : public BtProgressInfoFile {
+private:
+ BtContextHandle btContext;
+ const Option* option;
+ Logger* logger;
+ PieceStorageHandle pieceStorage;
+ BtRuntimeHandle btRuntime;
+ PeerStorageHandle peerStorage;
+ string filename;
+
+ FILE* openFile(const string& filename, const string& mode) const;
+public:
+ DefaultBtProgressInfoFile(const BtContextHandle& btContext,
+ const Option* option);
+ virtual ~DefaultBtProgressInfoFile();
+
+ void setBtRuntime(const BtRuntimeHandle& btRuntime) {
+ this->btRuntime = btRuntime;
+ }
+ BtRuntimeHandle getBtRuntime() const { return btRuntime; }
+
+ void setPieceStorage(const PieceStorageHandle& pieceStorage) {
+ this->pieceStorage = pieceStorage;
+ }
+ PieceStorageHandle getPieceStorage() const { return pieceStorage; }
+
+ void setPeerStorage(const PeerStorageHandle& peerStorage) {
+ this->peerStorage = peerStorage;
+ }
+ PeerStorageHandle getPeerStorage() const { return peerStorage; }
+
+ virtual void setFilename(const string& filename) {
+ this->filename = filename;
+ }
+ virtual string getFilename() { return filename; }
+
+ virtual bool exists();
+
+ virtual void save();
+
+ virtual void load();
+
+ virtual void removeFile();
+
+};
+
+#endif // _D_DEFAULT_BT_PROGRESS_INFO_FILE_H_
diff --git a/src/DefaultPeerStorage.cc b/src/DefaultPeerStorage.cc
new file mode 100644
index 00000000..456f99f2
--- /dev/null
+++ b/src/DefaultPeerStorage.cc
@@ -0,0 +1,174 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "DefaultPeerStorage.h"
+#include "LogFactory.h"
+#include "BtRegistry.h"
+
+extern PeerHandle nullPeer;
+
+DefaultPeerStorage::DefaultPeerStorage(BtContextHandle btContext,
+ const Option* option):
+ btContext(btContext),
+ option(option),
+ maxPeerListSize(MAX_PEER_LIST_SIZE),
+ peerEntryIdCounter(0),
+ btRuntime(BT_RUNTIME(btContext))
+{
+ logger = LogFactory::getInstance();
+}
+
+DefaultPeerStorage::~DefaultPeerStorage() {}
+
+bool DefaultPeerStorage::addPeer(const PeerHandle& peer) {
+ Peers::iterator itr = find(peers.begin(), peers.end(), peer);
+ if(itr == peers.end()) {
+ if(peers.size() >= (size_t)maxPeerListSize) {
+ deleteUnusedPeer(peers.size()-maxPeerListSize+1);
+ }
+ ++peerEntryIdCounter;
+ peer->entryId = peerEntryIdCounter;
+ peers.push_back(peer);
+ return true;
+ } else {
+ const PeerHandle& peer = *itr;
+ if(peer->error >= MAX_PEER_ERROR || peer->cuid != 0) {
+ return false;
+ } else {
+ *itr = peer;
+ return true;
+ }
+ }
+}
+
+void DefaultPeerStorage::addPeer(const Peers& peers) {
+ for(Peers::const_iterator itr = peers.begin();
+ itr != peers.end(); itr++) {
+ const PeerHandle& peer = *itr;
+ if(addPeer(peer)) {
+ logger->debug("Adding peer %s:%d",
+ peer->ipaddr.c_str(), peer->port);
+ }
+ }
+}
+
+const Peers& DefaultPeerStorage::getPeers() {
+ return peers;
+}
+
+class FindFinePeer {
+public:
+ bool operator()(const PeerHandle& peer) const {
+ return peer->cuid == 0 && peer->error < MAX_PEER_ERROR;
+ }
+};
+
+PeerHandle DefaultPeerStorage::getUnusedPeer() {
+ Peers::const_iterator itr = find_if(peers.begin(), peers.end(),
+ FindFinePeer());
+ if(itr == peers.end()) {
+ return nullPeer;
+ } else {
+ return *itr;
+ }
+}
+
+class FindPeer {
+private:
+ string ipaddr;
+ int port;
+public:
+ FindPeer(const string& ipaddr, int port):ipaddr(ipaddr), port(port) {}
+
+ bool operator()(const PeerHandle& peer) const {
+ return ipaddr == peer->ipaddr && port == peer->port;
+ }
+};
+
+PeerHandle DefaultPeerStorage::getPeer(const string& ipaddr,
+ int port) const {
+ Peers::const_iterator itr = find_if(peers.begin(), peers.end(),
+ FindPeer(ipaddr, port));
+ if(itr == peers.end()) {
+ return nullPeer;
+ } else {
+ return *itr;
+ }
+}
+
+int DefaultPeerStorage::countPeer() const {
+ return peers.size();
+}
+
+bool DefaultPeerStorage::isPeerAvailable() {
+ return getUnusedPeer() != nullPeer;
+}
+
+Peers DefaultPeerStorage::getActivePeers() {
+ Peers activePeers;
+ for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
+ PeerHandle& peer = *itr;
+ if(peer->isActive()) {
+ activePeers.push_back(peer);
+ }
+ }
+ return activePeers;
+}
+
+TransferStat DefaultPeerStorage::calculateStat() {
+ TransferStat stat;
+ Peers activePeers = getActivePeers();
+ for(Peers::iterator itr = activePeers.begin();
+ itr != activePeers.end(); itr++) {
+ PeerHandle& peer = *itr;
+ stat.downloadSpeed += peer->calculateDownloadSpeed();
+ stat.uploadSpeed += peer->calculateUploadSpeed();
+ stat.sessionDownloadLength += peer->getSessionDownloadLength();
+ stat.sessionUploadLength += peer->getSessionUploadLength();
+ }
+ return stat;
+}
+
+void DefaultPeerStorage::deleteUnusedPeer(int delSize) {
+ for(Peers::iterator itr = peers.begin();
+ itr != peers.end() && delSize > 0;) {
+ const PeerHandle& p = *itr;
+ if(p->cuid == 0) {
+ itr = peers.erase(itr);
+ delSize--;
+ } else {
+ itr++;
+ }
+ }
+}
diff --git a/src/DefaultPeerStorage.h b/src/DefaultPeerStorage.h
new file mode 100644
index 00000000..daabb69d
--- /dev/null
+++ b/src/DefaultPeerStorage.h
@@ -0,0 +1,90 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_PEER_STORAGE_H_
+#define _D_DEFAULT_PEER_STORAGE_H_
+
+#include "PeerStorage.h"
+#include "BtContext.h"
+#include "Option.h"
+#include "Logger.h"
+#include "BtRuntime.h"
+
+#define MAX_PEER_LIST_SIZE 100
+#define MAX_PEER_ERROR 5
+
+class DefaultPeerStorage : public PeerStorage {
+private:
+ BtContextHandle btContext;
+ const Option* option;
+ Peers peers;
+ int maxPeerListSize;
+ int peerEntryIdCounter;
+ Logger* logger;
+ BtRuntimeHandle btRuntime;
+public:
+ DefaultPeerStorage(BtContextHandle btContext, const Option* option);
+ virtual ~DefaultPeerStorage();
+
+ void setBtRuntime(const BtRuntimeHandle& btRuntime) {
+ this->btRuntime = btRuntime;
+ }
+ BtRuntimeHandle getBtRuntime() const { return btRuntime; }
+
+ virtual bool addPeer(const PeerHandle& peer);
+
+ int countPeer() const;
+
+ virtual PeerHandle getUnusedPeer();
+
+ PeerHandle getPeer(const string& ipaddr, int port) const;
+
+ virtual void addPeer(const Peers& peers);
+
+ virtual const Peers& getPeers();
+
+ virtual bool isPeerAvailable();
+
+ virtual Peers getActivePeers();
+
+ virtual TransferStat calculateStat();
+
+ void setMaxPeerListSize(int size) { this->maxPeerListSize = size; }
+
+ int getMaxPeerListSize() const { return maxPeerListSize; }
+
+ void deleteUnusedPeer(int delSize);
+};
+
+#endif // _D_DEFAULT_PEER_STORAGE_H_
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
new file mode 100644
index 00000000..c819934f
--- /dev/null
+++ b/src/DefaultPieceStorage.cc
@@ -0,0 +1,433 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "DefaultPieceStorage.h"
+#include "LogFactory.h"
+#include "prefs.h"
+#include "DirectDiskAdaptor.h"
+#include "MultiDiskAdaptor.h"
+#include "CopyDiskAdaptor.h"
+#include "DefaultDiskWriter.h"
+#include "MultiDiskWriter.h"
+#include "PreAllocationDiskWriter.h"
+#include "DlAbortEx.h"
+
+DefaultPieceStorage::DefaultPieceStorage(BtContextHandle btContext, const Option* option):
+ btContext(btContext),
+ endGamePieceNum(END_GAME_PIECE_NUM),
+ option(option)
+{
+ bitfieldMan = new BitfieldMan(btContext->getPieceLength(),
+ btContext->getTotalLength());
+ logger = LogFactory::getInstance();
+}
+
+DefaultPieceStorage::~DefaultPieceStorage() {
+ delete bitfieldMan;
+}
+
+bool DefaultPieceStorage::hasMissingPiece(const PeerHandle& peer) {
+ return bitfieldMan->hasMissingPiece(peer->getBitfield(),
+ peer->getBitfieldLength());
+}
+
+bool DefaultPieceStorage::isEndGame() {
+ return bitfieldMan->countMissingBlock() <= endGamePieceNum;
+}
+
+int DefaultPieceStorage::getMissingPieceIndex(const PeerHandle& peer) {
+ int index = -1;
+ if(isEndGame()) {
+ index = bitfieldMan->getMissingIndex(peer->getBitfield(),
+ peer->getBitfieldLength());
+ } else {
+ index = bitfieldMan->getMissingUnusedIndex(peer->getBitfield(),
+ peer->getBitfieldLength());
+ }
+ return index;
+}
+
+Piece DefaultPieceStorage::checkOutPiece(int index) {
+ if(index == -1) {
+ return Piece::nullPiece;
+ }
+ bitfieldMan->setUseBit(index);
+
+ Piece piece = findUsedPiece(index);
+ if(Piece::isNull(piece)) {
+ Piece piece(index, bitfieldMan->getBlockLength(index));
+ addUsedPiece(piece);
+ return piece;
+ } else {
+ return piece;
+ }
+}
+
+void DefaultPieceStorage::addUsedPiece(const Piece& piece) {
+ // TODO ? if nullPiece
+ usedPieces.push_back(piece);
+}
+
+class FindPiece {
+private:
+ int index;
+public:
+ FindPiece(int index):index(index) {}
+
+ bool operator()(const Piece& piece) {
+ return piece.getIndex() == index;
+ }
+};
+
+Piece DefaultPieceStorage::findUsedPiece(int index) const {
+ Pieces::const_iterator itr = find_if(usedPieces.begin(),
+ usedPieces.end(),
+ FindPiece(index));
+ if(itr == usedPieces.end()) {
+ return Piece::nullPiece;
+ } else {
+ return *itr;
+ }
+}
+
+Piece DefaultPieceStorage::getMissingPiece(const PeerHandle& peer) {
+ int index = getMissingPieceIndex(peer);
+ return checkOutPiece(index);
+}
+
+int DefaultPieceStorage::getMissingFastPieceIndex(const PeerHandle& peer) {
+ int index = -1;
+ if(peer->isFastExtensionEnabled() && peer->countFastSet() > 0) {
+ BitfieldMan tempBitfield(bitfieldMan->getBlockLength(),
+ bitfieldMan->getTotalLength());
+ for(Integers::const_iterator itr = peer->getFastSet().begin();
+ itr != peer->getFastSet().end(); itr++) {
+ if(!bitfieldMan->isBitSet(index) && peer->hasPiece(*itr)) {
+ tempBitfield.setBit(*itr);
+ }
+ }
+ if(isEndGame()) {
+ index = bitfieldMan->getMissingIndex(tempBitfield.getBitfield(),
+ tempBitfield.getBitfieldLength());
+ } else {
+ index = bitfieldMan->getMissingUnusedIndex(tempBitfield.getBitfield(),
+ tempBitfield.getBitfieldLength());
+ }
+ }
+ return index;
+}
+
+Piece DefaultPieceStorage::getMissingFastPiece(const PeerHandle& peer) {
+ int index = getMissingFastPieceIndex(peer);
+ return checkOutPiece(index);
+}
+
+void DefaultPieceStorage::deleteUsedPiece(const Piece& piece) {
+ if(Piece::isNull(piece)) {
+ return;
+ }
+ Pieces::iterator itr = find(usedPieces.begin(), usedPieces.end(), piece);
+ if(itr != usedPieces.end()) {
+ usedPieces.erase(itr);
+ }
+}
+
+void DefaultPieceStorage::reduceUsedPieces(int delMax) {
+ int toDelete = usedPieces.size()-delMax;
+ if(toDelete <= 0) {
+ return;
+ }
+ int fillRate = 10;
+ while(fillRate < 50) {
+ int deleted = deleteUsedPiecesByFillRate(fillRate, toDelete);
+ if(deleted == 0) {
+ break;
+ }
+ toDelete -= deleted;
+ fillRate += 10;
+ }
+}
+
+int DefaultPieceStorage::deleteUsedPiecesByFillRate(int fillRate,
+ int toDelete) {
+ int deleted = 0;
+ for(Pieces::iterator itr = usedPieces.begin();
+ itr != usedPieces.end() && deleted < toDelete;) {
+ Piece& piece = *itr;
+ if(!bitfieldMan->isUseBitSet(piece.getIndex()) &&
+ piece.countCompleteBlock() <= piece.countBlock()*(fillRate/100.0)) {
+ logger->debug("Deleting used piece index=%d, fillRate(%%)=%d<=%d",
+ piece.getIndex(),
+ (piece.countCompleteBlock()*100)/piece.countBlock(),
+ fillRate);
+ itr = usedPieces.erase(itr);
+ deleted++;
+ } else {
+ itr++;
+ }
+ }
+ return deleted;
+}
+
+void DefaultPieceStorage::completePiece(const Piece& piece) {
+ if(Piece::isNull(piece)) {
+ return;
+ }
+ deleteUsedPiece(piece);
+ if(!isEndGame()) {
+ reduceUsedPieces(100);
+ }
+ if(downloadFinished()) {
+ return;
+ }
+ bitfieldMan->setBit(piece.getIndex());
+ bitfieldMan->unsetUseBit(piece.getIndex());
+ if(downloadFinished()) {
+ diskAdaptor->onDownloadComplete();
+ if(isSelectiveDownloadingMode()) {
+ logger->notice(_("Download of selected files was complete."));
+ finishSelectiveDownloadingMode();
+ } else {
+ logger->info(_("The download was complete."));
+ }
+ }
+}
+
+bool DefaultPieceStorage::isSelectiveDownloadingMode() {
+ return bitfieldMan->isFilterEnabled();
+}
+
+void DefaultPieceStorage::finishSelectiveDownloadingMode() {
+ bitfieldMan->clearFilter();
+ diskAdaptor->addAllDownloadEntry();
+}
+
+// not unittested
+void DefaultPieceStorage::cancelPiece(const Piece& piece) {
+ if(Piece::isNull(piece)) {
+ return;
+ }
+ updatePiece(piece);
+ bitfieldMan->unsetUseBit(piece.getIndex());
+ if(!isEndGame()) {
+ if(piece.countCompleteBlock() == 0) {
+ deleteUsedPiece(piece);
+ }
+ }
+}
+
+// not unittested
+void DefaultPieceStorage::updatePiece(const Piece& piece) {
+ if(Piece::isNull(piece)) {
+ return;
+ }
+ Pieces::iterator itr = find(usedPieces.begin(), usedPieces.end(),
+ piece);
+ if(itr != usedPieces.end()) {
+ *itr = piece;
+ }
+}
+
+// not unittested
+void DefaultPieceStorage::syncPiece(Piece& piece) {
+ if(Piece::isNull(piece)) {
+ return;
+ }
+ Pieces::iterator itr = find(usedPieces.begin(), usedPieces.end(),
+ piece);
+ if(itr != usedPieces.end()) {
+ piece = *itr;
+ return;
+ } else {
+ // hasPiece(piece.getIndex()) is true, then set all bit of
+ // piece.bitfield to 1
+ if(hasPiece(piece.getIndex())) {
+ piece.setAllBlock();
+ }
+ }
+}
+
+bool DefaultPieceStorage::hasPiece(int index) {
+ return bitfieldMan->isBitSet(index);
+}
+
+long long int DefaultPieceStorage::getTotalLength() {
+ return bitfieldMan->getTotalLength();
+}
+
+long long int DefaultPieceStorage::getFilteredTotalLength() {
+ return bitfieldMan->getFilteredTotalLength();
+}
+
+long long int DefaultPieceStorage::getCompletedLength() {
+ return bitfieldMan->getCompletedLength();
+}
+
+long long int DefaultPieceStorage::getFilteredCompletedLength() {
+ return bitfieldMan->getFilteredCompletedLength();
+}
+
+// not unittested
+void DefaultPieceStorage::setFileFilter(const Strings& filePaths) {
+ if(btContext->getFileMode() != BtContext::MULTI || filePaths.empty()) {
+ return;
+ }
+ diskAdaptor->removeAllDownloadEntry();
+ for(Strings::const_iterator pitr = filePaths.begin();
+ pitr != filePaths.end(); pitr++) {
+ if(!diskAdaptor->addDownloadEntry(*pitr)) {
+ throw new DlAbortEx("No such file entry %s", (*pitr).c_str());
+ }
+ FileEntryHandle fileEntry = diskAdaptor->getFileEntryFromPath(*pitr);
+ bitfieldMan->addFilter(fileEntry->getOffset(), fileEntry->getLength());
+ }
+ bitfieldMan->enableFilter();
+}
+
+void DefaultPieceStorage::setFileFilter(const Integers& fileIndexes) {
+ Strings filePaths;
+ const FileEntries& entries = diskAdaptor->getFileEntries();
+ for(int i = 0; i < (int)entries.size(); i++) {
+ if(find(fileIndexes.begin(), fileIndexes.end(), i+1) != fileIndexes.end()) {
+ logger->debug("index=%d is %s", i+1, entries.at(i)->getPath().c_str());
+ filePaths.push_back(entries.at(i)->getPath());
+ }
+ }
+ setFileFilter(filePaths);
+}
+
+// not unittested
+void DefaultPieceStorage::clearFileFilter() {
+ bitfieldMan->clearFilter();
+ diskAdaptor->addAllDownloadEntry();
+}
+
+// not unittested
+bool DefaultPieceStorage::downloadFinished() {
+ return bitfieldMan->isAllBitSet();
+}
+
+// not unittested
+void DefaultPieceStorage::initStorage() {
+ if(diskAdaptor) {
+ delete diskAdaptor;
+ diskAdaptor = 0;
+ }
+ if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
+ if(btContext->getFileMode() == BtContext::SINGLE) {
+ diskAdaptor = new DirectDiskAdaptor(new DefaultDiskWriter(btContext->getTotalLength()));
+ } else {
+ diskAdaptor = new MultiDiskAdaptor(new MultiDiskWriter(btContext->getPieceLength()));
+ }
+ } else {
+ diskAdaptor = new CopyDiskAdaptor(new PreAllocationDiskWriter(btContext->getTotalLength()));
+ ((CopyDiskAdaptor*)diskAdaptor)->setTempFilename(btContext->getName()+".a2tmp");
+ }
+ string storeDir = option->get(PREF_DIR);
+ if(storeDir == "") {
+ storeDir = ".";
+ }
+ if(btContext->getFileMode() == BtContext::MULTI) {
+ storeDir += "/"+btContext->getName();
+ }
+ diskAdaptor->setStoreDir(storeDir);
+ diskAdaptor->setFileEntries(btContext->getFileEntries());
+}
+
+void DefaultPieceStorage::setBitfield(const unsigned char* bitfield,
+ int bitfieldLength) {
+ bitfieldMan->setBitfield(bitfield, bitfieldLength);
+}
+
+int DefaultPieceStorage::getBitfieldLength() {
+ return bitfieldMan->getBitfieldLength();
+}
+
+const unsigned char* DefaultPieceStorage::getBitfield() {
+ return bitfieldMan->getBitfield();
+}
+
+DiskAdaptor* DefaultPieceStorage::getDiskAdaptor() {
+ return diskAdaptor;
+}
+
+int DefaultPieceStorage::getPieceLength(int index) {
+ return bitfieldMan->getBlockLength(index);
+}
+
+void DefaultPieceStorage::advertisePiece(int cuid, int index) {
+ HaveEntry entry(cuid, index);
+ haves.push_front(entry);
+}
+
+Integers DefaultPieceStorage::getAdvertisedPieceIndexes(int myCuid,
+ const Time& lastCheckTime) {
+ Integers indexes;
+ for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
+ const Haves::value_type& have = *itr;
+ if(have.getCuid() == myCuid) {
+ continue;
+ }
+ if(lastCheckTime.isNewer(have.getRegisteredTime())) {
+ break;
+ }
+ indexes.push_back(have.getIndex());
+ }
+ return indexes;
+}
+
+class FindElapsedHave
+{
+private:
+ int elapsed;
+public:
+ FindElapsedHave(int elapsed):elapsed(elapsed) {}
+
+ bool operator()(const HaveEntry& have) {
+ if(have.getRegisteredTime().elapsed(elapsed)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+void DefaultPieceStorage::removeAdvertisedPiece(int elapsed) {
+ Haves::iterator itr =
+ find_if(haves.begin(), haves.end(), FindElapsedHave(elapsed));
+ if(itr != haves.end()) {
+ logger->debug("Removed %d have entries.", haves.end()-itr);
+ haves.erase(itr, haves.end());
+ }
+}
diff --git a/src/DefaultPieceStorage.h b/src/DefaultPieceStorage.h
new file mode 100644
index 00000000..4b9a2066
--- /dev/null
+++ b/src/DefaultPieceStorage.h
@@ -0,0 +1,158 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_DEFAULT_PIECE_STORAGE_H_
+#define _D_DEFAULT_PIECE_STORAGE_H_
+
+#include "PieceStorage.h"
+#include "BtContext.h"
+#include "DiskAdaptor.h"
+#include "BitfieldMan.h"
+#include "Logger.h"
+#include "Option.h"
+#include "Piece.h"
+
+#define END_GAME_PIECE_NUM 20
+
+class HaveEntry {
+private:
+ int cuid;
+ int index;
+ Time registeredTime;
+public:
+ HaveEntry(int cuid, int index):
+ cuid(cuid),
+ index(index) {}
+
+ int getCuid() const { return cuid; }
+
+ int getIndex() const { return index; }
+
+ const Time& getRegisteredTime() const { return registeredTime; }
+};
+
+typedef deque<HaveEntry> Haves;
+
+class DefaultPieceStorage : public PieceStorage {
+private:
+ BtContextHandle btContext;
+ BitfieldMan* bitfieldMan;
+ DiskAdaptor* diskAdaptor;
+ Pieces usedPieces;
+ int endGamePieceNum;
+ Logger* logger;
+ const Option* option;
+ Haves haves;
+
+ int getMissingPieceIndex(const PeerHandle& peer);
+ int getMissingFastPieceIndex(const PeerHandle& peer);
+ Piece checkOutPiece(int index);
+ void addUsedPiece(const Piece& piece);
+ Piece findUsedPiece(int index) const;
+ int deleteUsedPiecesByFillRate(int fillRate, int toDelete);
+ void reduceUsedPieces(int delMax);
+ void deleteUsedPiece(const Piece& piece);
+public:
+ DefaultPieceStorage(BtContextHandle btContext, const Option* option);
+ virtual ~DefaultPieceStorage();
+
+ virtual bool hasMissingPiece(const PeerHandle& peer);
+
+ virtual Piece getMissingPiece(const PeerHandle& peer);
+
+ virtual Piece getMissingFastPiece(const PeerHandle& peer);
+
+ virtual void completePiece(const Piece& piece);
+
+ virtual void cancelPiece(const Piece& piece);
+
+ virtual void updatePiece(const Piece& piece);
+
+ virtual void syncPiece(Piece& piece);
+
+ virtual bool hasPiece(int index);
+
+ virtual long long int getTotalLength();
+
+ virtual long long int getFilteredTotalLength();
+
+ virtual long long int getCompletedLength();
+
+ virtual long long int getFilteredCompletedLength();
+
+ virtual void initStorage();
+
+ virtual void setFileFilter(const Strings& filePaths);
+
+ virtual void setFileFilter(const Integers& fileIndexes);
+
+ virtual void clearFileFilter();
+
+ virtual bool downloadFinished();
+
+ virtual void setBitfield(const unsigned char* bitfield,
+ int bitfieldLength);
+
+ virtual int getBitfieldLength();
+
+ virtual const unsigned char* getBitfield();
+
+ void setEndGamePieceNum(int num) {
+ endGamePieceNum = num;
+ }
+
+ int getEndGamePieceNum() const {
+ return endGamePieceNum;
+ }
+
+ virtual bool isSelectiveDownloadingMode();
+
+ virtual void finishSelectiveDownloadingMode();
+
+ virtual bool isEndGame();
+
+ virtual DiskAdaptor* getDiskAdaptor();
+
+ virtual int getPieceLength(int index);
+
+ virtual void advertisePiece(int cuid, int index);
+
+ virtual Integers getAdvertisedPieceIndexes(int myCuid,
+ const Time& lastCheckTime);
+
+ virtual void removeAdvertisedPiece(int elapsed);
+
+};
+
+#endif // _D_DEFAULT_PIECE_STORAGE_H_
diff --git a/src/DelegatingPeerListProcessor.cc b/src/DelegatingPeerListProcessor.cc
index b91554bb..38f9395c 100644
--- a/src/DelegatingPeerListProcessor.cc
+++ b/src/DelegatingPeerListProcessor.cc
@@ -54,4 +54,5 @@ bool DelegatingPeerListProcessor::canHandle(const MetaEntry* peersEntry) const {
return true;
}
}
+ return false;
}
diff --git a/src/DirectDiskAdaptor.cc b/src/DirectDiskAdaptor.cc
index f360393c..290516e7 100644
--- a/src/DirectDiskAdaptor.cc
+++ b/src/DirectDiskAdaptor.cc
@@ -39,7 +39,7 @@ DirectDiskAdaptor::DirectDiskAdaptor(DiskWriter* diskWriter):DiskAdaptor(diskWri
DirectDiskAdaptor::~DirectDiskAdaptor() {}
string DirectDiskAdaptor::getFilePath() const {
- return storeDir+"/"+fileEntries.front().path;
+ return storeDir+"/"+fileEntries.front()->getPath();
}
void DirectDiskAdaptor::onDownloadComplete() {
diff --git a/src/Directory.cc b/src/Directory.cc
index f3e2f2b3..c342f94b 100644
--- a/src/Directory.cc
+++ b/src/Directory.cc
@@ -42,6 +42,8 @@
Directory::Directory(const string& name):name(name) {}
+Directory::Directory() {}
+
Directory::~Directory() {
for(Files::iterator itr = files.begin(); itr != files.end(); itr++) {
delete *itr;
@@ -49,6 +51,9 @@ Directory::~Directory() {
}
void Directory::createDir(const string& parentDir, bool recursive) const {
+ if(name.size() == 0) {
+ return;
+ }
string path = parentDir+"/"+name;
File f(path);
if(f.exists()) {
diff --git a/src/Directory.h b/src/Directory.h
index 1eef65fb..e3fb8cd9 100644
--- a/src/Directory.h
+++ b/src/Directory.h
@@ -48,10 +48,13 @@ private:
Files files;
public:
Directory(const string& name);
+ Directory();
~Directory();
void createDir(const string& parentDir, bool recursive) const;
void addFile(Directory* directory);
};
+typedef SharedHandle<Directory> DirectoryHandle;
+
#endif // _D_DIRECTORY_H_
diff --git a/src/DiskAdaptor.cc b/src/DiskAdaptor.cc
index 2ed4d2c2..9044b31b 100644
--- a/src/DiskAdaptor.cc
+++ b/src/DiskAdaptor.cc
@@ -36,15 +36,12 @@
#include "DlAbortEx.h"
#include "LogFactory.h"
-DiskAdaptor::DiskAdaptor(DiskWriter* diskWriter):diskWriter(diskWriter), topDir(NULL) {
+DiskAdaptor::DiskAdaptor(DiskWriter* diskWriter):diskWriter(diskWriter) {
logger = LogFactory::getInstance();
}
DiskAdaptor::~DiskAdaptor() {
delete diskWriter;
- if(topDir != NULL) {
- delete topDir;
- }
}
void DiskAdaptor::openFile() {
@@ -75,10 +72,10 @@ string DiskAdaptor::sha1Sum(long long int offset, long long int length) {
return diskWriter->sha1Sum(offset, length);
}
-FileEntry DiskAdaptor::getFileEntryFromPath(const string& fileEntryPath) const {
+FileEntryHandle DiskAdaptor::getFileEntryFromPath(const string& fileEntryPath) const {
for(FileEntries::const_iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
- if(itr->path == fileEntryPath) {
+ if((*itr)->getPath() == fileEntryPath) {
return *itr;
}
}
@@ -88,8 +85,8 @@ FileEntry DiskAdaptor::getFileEntryFromPath(const string& fileEntryPath) const {
bool DiskAdaptor::addDownloadEntry(const string& fileEntryPath) {
for(FileEntries::iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
- if(itr->path == fileEntryPath) {
- itr->requested = true;
+ if((*itr)->getPath() == fileEntryPath) {
+ (*itr)->setRequested(true);
return true;
}
}
@@ -100,20 +97,20 @@ bool DiskAdaptor::addDownloadEntry(int index) {
if(fileEntries.size() <= (unsigned int)index) {
return false;
}
- fileEntries.at(index).requested = true;
+ fileEntries.at(index)->setRequested(true);
return true;
}
void DiskAdaptor::addAllDownloadEntry() {
for(FileEntries::iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
- itr->requested = true;
+ (*itr)->setRequested(true);
}
}
void DiskAdaptor::removeAllDownloadEntry() {
for(FileEntries::iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
- itr->requested = false;
+ (*itr)->setRequested(false);
}
}
diff --git a/src/DiskAdaptor.h b/src/DiskAdaptor.h
index 276def84..a172cd4f 100644
--- a/src/DiskAdaptor.h
+++ b/src/DiskAdaptor.h
@@ -40,13 +40,13 @@
#include "Directory.h"
#include "DiskWriter.h"
#include "Logger.h"
+#include "FileEntry.h"
class DiskAdaptor {
protected:
DiskWriter* diskWriter;
string storeDir;
FileEntries fileEntries;
- const Directory* topDir;
const Logger* logger;
virtual string getFilePath() const = 0;
public:
@@ -66,7 +66,9 @@ public:
void setFileEntries(const FileEntries& fileEntries) {
this->fileEntries = fileEntries;
}
- FileEntry getFileEntryFromPath(const string& fileEntryPath) const;
+
+ FileEntryHandle getFileEntryFromPath(const string& fileEntryPath) const;
+
const FileEntries& getFileEntries() const { return fileEntries; }
bool addDownloadEntry(const string& fileEntryPath);
@@ -75,15 +77,8 @@ public:
void removeAllDownloadEntry();
void setStoreDir(const string& storeDir) { this->storeDir = storeDir; }
- string getStoreDir() const { return this->storeDir; }
- void setTopDir(const Directory* dirctory) {
- if(this->topDir != NULL) {
- delete topDir;
- }
- this->topDir = dirctory;
- }
- const Directory* getTopDir() const { return this->topDir; }
+ string getStoreDir() const { return this->storeDir; }
};
#endif // _D_DISK_ADAPTOR_H_
diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc
index 6ac1d745..2bb84da2 100644
--- a/src/DownloadEngineFactory.cc
+++ b/src/DownloadEngineFactory.cc
@@ -49,6 +49,10 @@
# include "UnionSeedCriteria.h"
# include "TimeSeedCriteria.h"
# include "ShareRatioSeedCriteria.h"
+# include "DefaultPieceStorage.h"
+# include "DefaultPeerStorage.h"
+# include "DefaultBtAnnounce.h"
+# include "DefaultBtProgressInfoFile.h"
#endif // ENABLE_BITTORRENT
ConsoleDownloadEngine*
@@ -76,8 +80,8 @@ DownloadEngineFactory::newConsoleEngine(const Option* op,
#ifdef ENABLE_BITTORRENT
TorrentConsoleDownloadEngine*
-DownloadEngineFactory::newTorrentConsoleEngine(const Option* op,
- const string& torrentFile,
+DownloadEngineFactory::newTorrentConsoleEngine(const BtContextHandle& btContext,
+ const Option* op,
const Strings& targetFiles)
{
TorrentConsoleDownloadEngine* te = new TorrentConsoleDownloadEngine();
@@ -86,19 +90,44 @@ DownloadEngineFactory::newTorrentConsoleEngine(const Option* op,
te->segmentMan = new SegmentMan();
te->segmentMan->diskWriter = byteArrayDiskWriter;
te->segmentMan->option = op;
- te->torrentMan = new TorrentMan();
- te->torrentMan->setStoreDir(op->get(PREF_DIR));
- te->torrentMan->option = op;
+ BtRuntimeHandle btRuntime(new BtRuntime());
+ BtRegistry::registerBtRuntime(btContext->getInfoHashAsString(), btRuntime);
+
+ PieceStorageHandle pieceStorage(new DefaultPieceStorage(btContext, op));
+ BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(), pieceStorage);
+
+ PeerStorageHandle peerStorage(new DefaultPeerStorage(btContext, op));
+ BtRegistry::registerPeerStorage(btContext->getInfoHashAsString(), peerStorage);
+
+ BtAnnounceHandle btAnnounce(new DefaultBtAnnounce(btContext, op));
+ BtRegistry::registerBtAnnounce(btContext->getInfoHashAsString(), btAnnounce);
+ btAnnounce->shuffleAnnounce();
+
+ BtProgressInfoFileHandle btProgressInfoFile(new DefaultBtProgressInfoFile(btContext, op));
+ BtRegistry::registerBtProgressInfoFile(btContext->getInfoHashAsString(),
+ btProgressInfoFile);
+
+ te->setBtContext(btContext);
+ // initialize file storage
+ pieceStorage->initStorage();
+ if(btProgressInfoFile->exists()) {
+ // load .aria2 file if it exists.
+ btProgressInfoFile->load();
+ pieceStorage->getDiskAdaptor()->openExistingFile();
+ } else {
+ pieceStorage->getDiskAdaptor()->initAndOpenFile();
+ }
+
Integers selectIndexes;
Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes);
if(selectIndexes.size()) {
- te->torrentMan->setup(torrentFile, selectIndexes);
+ pieceStorage->setFileFilter(selectIndexes);
} else {
- te->torrentMan->setup(torrentFile, targetFiles);
+ pieceStorage->setFileFilter(targetFiles);
}
PeerListenCommand* listenCommand =
- new PeerListenCommand(te->torrentMan->getNewCuid(), te);
+ new PeerListenCommand(btRuntime->getNewCuid(), te, btContext);
int port;
int listenPort = op->getAsInt(PREF_LISTEN_PORT);
if(listenPort == -1) {
@@ -110,31 +139,39 @@ DownloadEngineFactory::newTorrentConsoleEngine(const Option* op,
printf(_("Errors occurred while binding port.\n"));
exit(EXIT_FAILURE);
}
- te->torrentMan->setPort(port);
+ btRuntime->setListenPort(port);
te->commands.push_back(listenCommand);
- te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
- te));
- te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
- te));
- te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
+ te->commands.push_back(new TrackerWatcherCommand(btRuntime->getNewCuid(),
+ te,
+ btContext));
+ te->commands.push_back(new TrackerUpdateCommand(btRuntime->getNewCuid(),
+ te,
+ btContext));
+ te->commands.push_back(new TorrentAutoSaveCommand(btRuntime->getNewCuid(),
te,
+ btContext,
op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
- te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(),
- te, 10));
- te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(),
- te, 10));
+ te->commands.push_back(new PeerChokeCommand(btRuntime->getNewCuid(),
+ te,
+ btContext,
+ 10));
+ te->commands.push_back(new HaveEraseCommand(btRuntime->getNewCuid(),
+ te,
+ btContext,
+ 10));
SharedHandle<UnionSeedCriteria> unionCri = new UnionSeedCriteria();
if(op->defined(PREF_SEED_TIME)) {
unionCri->addSeedCriteria(new TimeSeedCriteria(op->getAsInt(PREF_SEED_TIME)*60));
}
if(op->defined(PREF_SEED_RATIO)) {
- unionCri->addSeedCriteria(new ShareRatioSeedCriteria(op->getAsDouble(PREF_SEED_RATIO), te->torrentMan));
+ unionCri->addSeedCriteria(new ShareRatioSeedCriteria(op->getAsDouble(PREF_SEED_RATIO), btContext));
}
if(unionCri->getSeedCriterion().size() > 0) {
- te->commands.push_back(new SeedCheckCommand(te->torrentMan->getNewCuid(),
+ te->commands.push_back(new SeedCheckCommand(btRuntime->getNewCuid(),
te,
+ btContext,
unionCri));
}
return te;
diff --git a/src/DownloadEngineFactory.h b/src/DownloadEngineFactory.h
index 33ee1299..f5f801c3 100644
--- a/src/DownloadEngineFactory.h
+++ b/src/DownloadEngineFactory.h
@@ -50,8 +50,8 @@ public:
#ifdef ENABLE_BITTORRENT
static TorrentConsoleDownloadEngine*
- newTorrentConsoleEngine(const Option* option,
- const string& torrentFile,
+ newTorrentConsoleEngine(const BtContextHandle& btContext,
+ const Option* option,
const Strings& targetFiles);
#endif // ENABLE_BITTORRENT
};
diff --git a/src/File.cc b/src/File.cc
index 459f6b53..0cd732b8 100644
--- a/src/File.cc
+++ b/src/File.cc
@@ -33,6 +33,7 @@
*/
/* copyright --> */
#include "File.h"
+#include "Util.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -83,3 +84,30 @@ long long int File::size() {
}
return fstat.st_size;
}
+
+bool File::mkdirs() {
+ if(isDir()) {
+ return false;
+ }
+ Strings dirs;
+ Util::slice(dirs, name, '/');
+ if(!dirs.size()) {
+ return true;
+ }
+ string accDir;
+ if(Util::startsWith(name, "/")) {
+ accDir = "/";
+ }
+ mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR;
+ for(Strings::const_iterator itr = dirs.begin(); itr != dirs.end();
+ itr++, accDir += "/") {
+ accDir += *itr;
+ if(File(accDir).isDir()) {
+ continue;
+ }
+ if(mkdir(accDir.c_str(), mode) == -1) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/src/File.h b/src/File.h
index 1e3e8134..033c6598 100644
--- a/src/File.h
+++ b/src/File.h
@@ -72,6 +72,15 @@ public:
*/
bool remove();
+ /**
+ * Creates the directory denoted by name.
+ * This method creates complete directory structure.
+ * Returns true if the directory is created successfully, otherwise returns
+ * false.
+ * If the directory already exists, then returns false.
+ */
+ bool mkdirs();
+
long long int size();
};
diff --git a/src/FileEntry.cc b/src/FileEntry.cc
new file mode 100644
index 00000000..1e74ffa8
--- /dev/null
+++ b/src/FileEntry.cc
@@ -0,0 +1,64 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "FileEntry.h"
+#include "File.h"
+#include "DlAbortEx.h"
+#include <libgen.h>
+
+FileEntry::FileEntry(const string& path,
+ long long int length,
+ long long int offset):
+ path(path), length(length), offset(offset),
+ extracted(false), requested(true) {}
+
+FileEntry::~FileEntry() {}
+
+void FileEntry::setupDir(const string& parentDir) {
+ string absPath = parentDir+"/"+path;
+ char* temp = strdup(absPath.c_str());
+ string dir = string(dirname(temp));
+ free(temp);
+ if(!dir.size()) {
+ return;
+ }
+ File f(dir);
+ if(f.isDir()) {
+ // nothing to do
+ } else if(f.exists()) {
+ throw new DlAbortEx("%s is not a directory.", dir.c_str());
+ } else if(!f.mkdirs()) {
+ throw new DlAbortEx("Failed to create directory %s.", dir.c_str());
+ }
+}
diff --git a/src/FileEntry.h b/src/FileEntry.h
index 5c7281d0..0113921a 100644
--- a/src/FileEntry.h
+++ b/src/FileEntry.h
@@ -38,18 +38,41 @@
#include "common.h"
class FileEntry {
-public:
+private:
string path;
long long int length;
long long int offset;
bool extracted;
bool requested;
- FileEntry(const string& path, long long int length, long long int offset):
- path(path), length(length), offset(offset),
- extracted(false), requested(true) {}
- ~FileEntry() {}
+public:
+ FileEntry(const string& path, long long int length, long long int offset);
+
+ ~FileEntry();
+
+ const string& getPath() const { return path; }
+
+ void setPath(const string& path) { this->path = path; }
+
+ long long int getLength() const { return length; }
+
+ void setLength(long long int length) { this->length = length; }
+
+ long long int getOffset() const { return offset; }
+
+ void setOffset(long long int offset) { this->offset = offset; }
+
+ bool isExtracted() const { return extracted; }
+
+ void setExtracted(bool flag) { this->extracted = flag; }
+
+ bool isRequested() const { return requested; }
+
+ void setRequested(bool flag) { this->requested = flag; }
+
+ void setupDir(const string& parentDir);
};
-typedef deque<FileEntry> FileEntries;
+typedef SharedHandle<FileEntry> FileEntryHandle;
+typedef deque<FileEntryHandle> FileEntries;
#endif // _D_FILE_ENTRY_H_
diff --git a/src/HandshakeMessage.cc b/src/HandshakeMessage.cc
index a3af8579..9e9fd390 100644
--- a/src/HandshakeMessage.cc
+++ b/src/HandshakeMessage.cc
@@ -93,7 +93,7 @@ string HandshakeMessage::toString() const {
void HandshakeMessage::check() const {
PeerMessageUtil::checkHandshake(this,
- peerInteraction->getTorrentMan()->getInfoHash());
+ peerInteraction->getBtContext()->getInfoHash());
}
bool HandshakeMessage::isFastExtensionSupported() const {
diff --git a/src/HandshakeMessage.h b/src/HandshakeMessage.h
index bd2ff0ae..6c931c91 100644
--- a/src/HandshakeMessage.h
+++ b/src/HandshakeMessage.h
@@ -36,7 +36,6 @@
#define _D_HANDSHAKE_MESSAGE_H_
#include "SimplePeerMessage.h"
-#include "TorrentMan.h"
#define PSTR "BitTorrent protocol"
#define HANDSHAKE_MESSAGE_LENGTH 68
diff --git a/src/HaveEraseCommand.cc b/src/HaveEraseCommand.cc
index d0fb3b2d..0758d10a 100644
--- a/src/HaveEraseCommand.cc
+++ b/src/HaveEraseCommand.cc
@@ -34,13 +34,21 @@
/* copyright --> */
#include "HaveEraseCommand.h"
+HaveEraseCommand::HaveEraseCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ int interval)
+ :BtContextAwareCommand(cuid, btContext),
+ e(e),
+ interval(interval) {}
+
bool HaveEraseCommand::execute() {
- if(e->torrentMan->isHalt()) {
+ if(btRuntime->isHalt()) {
return true;
}
if(cp.elapsed(interval)) {
cp.reset();
- e->torrentMan->removeAdvertisedPiece(5);
+ pieceStorage->removeAdvertisedPiece(5);
}
e->commands.push_back(this);
return false;
diff --git a/src/HaveEraseCommand.h b/src/HaveEraseCommand.h
index 7730111f..59a663bf 100644
--- a/src/HaveEraseCommand.h
+++ b/src/HaveEraseCommand.h
@@ -35,19 +35,19 @@
#ifndef _D_HAVE_ERASE_COMMAND_H_
#define _D_HAVE_ERASE_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
-class HaveEraseCommand : public Command {
+class HaveEraseCommand : public BtContextAwareCommand {
private:
TorrentDownloadEngine* e;
Time cp;
int interval;
public:
- HaveEraseCommand(int cuid, TorrentDownloadEngine* e, int interval)
- :Command(cuid),
- e(e),
- interval(interval) {}
+ HaveEraseCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ int interval);
virtual ~HaveEraseCommand() {}
diff --git a/src/Makefile.am b/src/Makefile.am
index 3807881e..e7860354 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,7 +69,6 @@ SRCS += MetaEntry.h\
MetaFileUtil.cc MetaFileUtil.h\
MetaEntryVisitor.h\
ShaVisitor.cc ShaVisitor.h\
- TorrentMan.cc TorrentMan.h\
PeerConnection.cc PeerConnection.h\
PeerMessageUtil.cc PeerMessageUtil.h\
PeerAbstractCommand.cc PeerAbstractCommand.h\
@@ -92,7 +91,7 @@ SRCS += MetaEntry.h\
CopyDiskAdaptor.cc CopyDiskAdaptor.h\
DirectDiskAdaptor.cc DirectDiskAdaptor.h\
MultiDiskAdaptor.cc MultiDiskAdaptor.h\
- FileEntry.h\
+ FileEntry.cc FileEntry.h\
TrackerUpdateCommand.cc TrackerUpdateCommand.h\
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
PeerChokeCommand.cc PeerChokeCommand.h\
@@ -125,7 +124,21 @@ SRCS += MetaEntry.h\
DefaultPeerListProcessor.cc DefaultPeerListProcessor.h\
CompactPeerListProcessor.cc CompactPeerListProcessor.h\
DelegatingPeerListProcessor.cc DelegatingPeerListProcessor.h\
- AnnounceList.h AnnounceList.cc
+ AnnounceTier.h\
+ AnnounceList.h AnnounceList.cc\
+ BtContext.h\
+ DefaultBtContext.cc DefaultBtContext.h\
+ PieceStorage.h\
+ DefaultPieceStorage.cc DefaultPieceStorage.h\
+ PeerService.h\
+ DefaultPeerStorage.cc DefaultPeerStorage.h\
+ BtAnnounce.h\
+ DefaultBtAnnounce.cc DefaultBtAnnounce.h\
+ BtRegistry.cc BtRegistry.h\
+ BtRuntime.h\
+ BtProgressInfoFile.h\
+ DefaultBtProgressInfoFile.cc DefaultBtProgressInfoFile.h\
+ BtContextAwareCommand.cc BtContextAwareCommand.h
endif # ENABLE_BITTORRENT
if ENABLE_METALINK
diff --git a/src/Makefile.in b/src/Makefile.in
index f52fe022..3ebd9e44 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -46,7 +46,6 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ MetaFileUtil.cc MetaFileUtil.h\
@ENABLE_BITTORRENT_TRUE@ MetaEntryVisitor.h\
@ENABLE_BITTORRENT_TRUE@ ShaVisitor.cc ShaVisitor.h\
-@ENABLE_BITTORRENT_TRUE@ TorrentMan.cc TorrentMan.h\
@ENABLE_BITTORRENT_TRUE@ PeerConnection.cc PeerConnection.h\
@ENABLE_BITTORRENT_TRUE@ PeerMessageUtil.cc PeerMessageUtil.h\
@ENABLE_BITTORRENT_TRUE@ PeerAbstractCommand.cc PeerAbstractCommand.h\
@@ -69,7 +68,7 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ CopyDiskAdaptor.cc CopyDiskAdaptor.h\
@ENABLE_BITTORRENT_TRUE@ DirectDiskAdaptor.cc DirectDiskAdaptor.h\
@ENABLE_BITTORRENT_TRUE@ MultiDiskAdaptor.cc MultiDiskAdaptor.h\
-@ENABLE_BITTORRENT_TRUE@ FileEntry.h\
+@ENABLE_BITTORRENT_TRUE@ FileEntry.cc FileEntry.h\
@ENABLE_BITTORRENT_TRUE@ TrackerUpdateCommand.cc TrackerUpdateCommand.h\
@ENABLE_BITTORRENT_TRUE@ ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
@ENABLE_BITTORRENT_TRUE@ PeerChokeCommand.cc PeerChokeCommand.h\
@@ -102,7 +101,21 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ DefaultPeerListProcessor.cc DefaultPeerListProcessor.h\
@ENABLE_BITTORRENT_TRUE@ CompactPeerListProcessor.cc CompactPeerListProcessor.h\
@ENABLE_BITTORRENT_TRUE@ DelegatingPeerListProcessor.cc DelegatingPeerListProcessor.h\
-@ENABLE_BITTORRENT_TRUE@ AnnounceList.h AnnounceList.cc
+@ENABLE_BITTORRENT_TRUE@ AnnounceTier.h\
+@ENABLE_BITTORRENT_TRUE@ AnnounceList.h AnnounceList.cc\
+@ENABLE_BITTORRENT_TRUE@ BtContext.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtContext.cc DefaultBtContext.h\
+@ENABLE_BITTORRENT_TRUE@ PieceStorage.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultPieceStorage.cc DefaultPieceStorage.h\
+@ENABLE_BITTORRENT_TRUE@ PeerService.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultPeerStorage.cc DefaultPeerStorage.h\
+@ENABLE_BITTORRENT_TRUE@ BtAnnounce.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtAnnounce.cc DefaultBtAnnounce.h\
+@ENABLE_BITTORRENT_TRUE@ BtRegistry.cc BtRegistry.h\
+@ENABLE_BITTORRENT_TRUE@ BtRuntime.h\
+@ENABLE_BITTORRENT_TRUE@ BtProgressInfoFile.h\
+@ENABLE_BITTORRENT_TRUE@ DefaultBtProgressInfoFile.cc DefaultBtProgressInfoFile.h\
+@ENABLE_BITTORRENT_TRUE@ BtContextAwareCommand.cc BtContextAwareCommand.h
@ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@@ -172,10 +185,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
BitfieldMan.cc BitfieldMan.h NameResolver.cc NameResolver.h \
MetaEntry.h Data.cc Data.h Dictionary.cc Dictionary.h List.cc \
List.h MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
- ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \
- PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \
- PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \
- PeerInitiateConnectionCommand.cc \
+ ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \
+ PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
+ PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h \
TorrentDownloadEngine.cc TorrentDownloadEngine.h \
@@ -189,11 +201,11 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
MultiDiskWriter.h DiskAdaptor.cc DiskAdaptor.h \
CopyDiskAdaptor.cc CopyDiskAdaptor.h DirectDiskAdaptor.cc \
DirectDiskAdaptor.h MultiDiskAdaptor.cc MultiDiskAdaptor.h \
- FileEntry.h TrackerUpdateCommand.cc TrackerUpdateCommand.h \
- ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
- PeerChokeCommand.cc PeerChokeCommand.h ChokeMessage.cc \
- ChokeMessage.h UnchokeMessage.cc UnchokeMessage.h \
- InterestedMessage.cc InterestedMessage.h \
+ FileEntry.cc FileEntry.h TrackerUpdateCommand.cc \
+ TrackerUpdateCommand.h ByteArrayDiskWriter.cc \
+ ByteArrayDiskWriter.h PeerChokeCommand.cc PeerChokeCommand.h \
+ ChokeMessage.cc ChokeMessage.h UnchokeMessage.cc \
+ UnchokeMessage.h InterestedMessage.cc InterestedMessage.h \
NotInterestedMessage.cc NotInterestedMessage.h HaveMessage.cc \
HaveMessage.h BitfieldMessage.cc BitfieldMessage.h \
RequestMessage.cc RequestMessage.h PieceMessage.cc \
@@ -211,9 +223,17 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
PeerListProcessor.h DefaultPeerListProcessor.cc \
DefaultPeerListProcessor.h CompactPeerListProcessor.cc \
CompactPeerListProcessor.h DelegatingPeerListProcessor.cc \
- DelegatingPeerListProcessor.h AnnounceList.h AnnounceList.cc \
- Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
- MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
+ DelegatingPeerListProcessor.h AnnounceTier.h AnnounceList.h \
+ AnnounceList.cc BtContext.h DefaultBtContext.cc \
+ DefaultBtContext.h PieceStorage.h DefaultPieceStorage.cc \
+ DefaultPieceStorage.h PeerService.h DefaultPeerStorage.cc \
+ DefaultPeerStorage.h BtAnnounce.h DefaultBtAnnounce.cc \
+ DefaultBtAnnounce.h BtRegistry.cc BtRegistry.h BtRuntime.h \
+ BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \
+ DefaultBtProgressInfoFile.h BtContextAwareCommand.cc \
+ BtContextAwareCommand.h Metalinker.cc Metalinker.h \
+ MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
+ MetalinkResource.h MetalinkProcessor.h \
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \
MetalinkRequestInfo.cc MetalinkRequestInfo.h
@ENABLE_ASYNC_DNS_TRUE@am__objects_1 = NameResolver.$(OBJEXT)
@@ -221,7 +241,6 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MetaFileUtil.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ShaVisitor.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ TorrentMan.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerConnection.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerMessageUtil.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerAbstractCommand.$(OBJEXT) \
@@ -243,6 +262,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ CopyDiskAdaptor.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DirectDiskAdaptor.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MultiDiskAdaptor.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ FileEntry.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ TrackerUpdateCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ByteArrayDiskWriter.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerChokeCommand.$(OBJEXT) \
@@ -270,7 +290,14 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ DefaultPeerListProcessor.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ CompactPeerListProcessor.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DelegatingPeerListProcessor.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ AnnounceList.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@ AnnounceList.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtContext.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultPieceStorage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultPeerStorage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtAnnounce.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtRegistry.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ DefaultBtProgressInfoFile.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ BtContextAwareCommand.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
@@ -598,6 +625,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtContextAwareCommand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtRegistry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ByteArrayDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CancelMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChokeMessage.Po@am__quote@
@@ -608,8 +637,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBox.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CopyDiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtAnnounce.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtContext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerStorage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPieceStorage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DelegatingPeerListProcessor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Dictionary.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DirectDiskAdaptor.Po@am__quote@
@@ -620,6 +654,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngineFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpConnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpDownloadCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpInitiateConnectionCommand.Po@am__quote@
@@ -687,7 +722,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentAutoSaveCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentConsoleDownloadEngine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentRequestInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerUpdateCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc
index 835a11f3..fc4a5400 100644
--- a/src/MultiDiskAdaptor.cc
+++ b/src/MultiDiskAdaptor.cc
@@ -46,14 +46,21 @@ string MultiDiskAdaptor::getFilePath() const {
return storeDir;
}
+void MultiDiskAdaptor::mkdir() const {
+ for(FileEntries::const_iterator itr = fileEntries.begin();
+ itr != fileEntries.end(); itr++) {
+ (*itr)->setupDir(storeDir);
+ }
+}
+
void MultiDiskAdaptor::openFile() {
- topDir->createDir(storeDir, true);
+ mkdir();
setDiskWriterFileEntries();
DiskAdaptor::openFile();
}
void MultiDiskAdaptor::initAndOpenFile() {
- topDir->createDir(storeDir, true);
+ mkdir();
setDiskWriterFileEntries();
DiskAdaptor::initAndOpenFile();
}
diff --git a/src/MultiDiskAdaptor.h b/src/MultiDiskAdaptor.h
index 0012779a..27fa74ee 100644
--- a/src/MultiDiskAdaptor.h
+++ b/src/MultiDiskAdaptor.h
@@ -41,6 +41,7 @@
class MultiDiskAdaptor : public DiskAdaptor {
private:
void setDiskWriterFileEntries();
+ void mkdir() const;
protected:
virtual string getFilePath() const;
public:
diff --git a/src/MultiDiskWriter.cc b/src/MultiDiskWriter.cc
index f49db771..b231d564 100644
--- a/src/MultiDiskWriter.cc
+++ b/src/MultiDiskWriter.cc
@@ -68,7 +68,7 @@ void MultiDiskWriter::setFileEntries(const FileEntries& fileEntries) {
void MultiDiskWriter::openFile(const string& filename) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
- (*itr)->diskWriter->openFile(filename+"/"+(*itr)->fileEntry.path);
+ (*itr)->diskWriter->openFile(filename+"/"+(*itr)->fileEntry->getPath());
}
}
@@ -76,7 +76,7 @@ void MultiDiskWriter::openFile(const string& filename) {
void MultiDiskWriter::initAndOpenFile(const string& filename) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
- (*itr)->diskWriter->initAndOpenFile(filename+"/"+(*itr)->fileEntry.path);
+ (*itr)->diskWriter->initAndOpenFile(filename+"/"+(*itr)->fileEntry->getPath());
}
}
@@ -90,7 +90,7 @@ void MultiDiskWriter::closeFile() {
void MultiDiskWriter::openExistingFile(const string& filename) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
- (*itr)->diskWriter->openExistingFile(filename+"/"+(*itr)->fileEntry.path);
+ (*itr)->diskWriter->openExistingFile(filename+"/"+(*itr)->fileEntry->getPath());
}
}
@@ -107,7 +107,7 @@ void MultiDiskWriter::writeData(const char* data, int len, long long int offset)
writing = true;
fileOffset = 0;
} else {
- fileOffset -= (*itr)->fileEntry.length;
+ fileOffset -= (*itr)->fileEntry->getLength();
}
}
if(!writing) {
@@ -116,14 +116,14 @@ void MultiDiskWriter::writeData(const char* data, int len, long long int offset)
}
bool MultiDiskWriter::isInRange(const DiskWriterEntry* entry, long long int offset) const {
- return entry->fileEntry.offset <= offset &&
- offset < entry->fileEntry.offset+entry->fileEntry.length;
+ return entry->fileEntry->getOffset() <= offset &&
+ offset < entry->fileEntry->getOffset()+entry->fileEntry->getLength();
}
int MultiDiskWriter::calculateLength(const DiskWriterEntry* entry, long long int fileOffset, int rem) const {
int length;
- if(entry->fileEntry.length < fileOffset+rem) {
- length = entry->fileEntry.length-fileOffset;
+ if(entry->fileEntry->getLength() < fileOffset+rem) {
+ length = entry->fileEntry->getLength()-fileOffset;
} else {
length = rem;
}
@@ -144,7 +144,7 @@ int MultiDiskWriter::readData(char* data, int len, long long int offset) {
reading = true;
fileOffset = 0;
} else {
- fileOffset -= (*itr)->fileEntry.length;
+ fileOffset -= (*itr)->fileEntry->getLength();
}
}
if(!reading) {
@@ -187,7 +187,7 @@ string MultiDiskWriter::sha1Sum(long long int offset, long long int length) {
reading = true;
fileOffset = 0;
} else {
- fileOffset -= (*itr)->fileEntry.length;
+ fileOffset -= (*itr)->fileEntry->getLength();
}
}
if(!reading) {
diff --git a/src/MultiDiskWriter.h b/src/MultiDiskWriter.h
index d0ac9655..c7e5d26c 100644
--- a/src/MultiDiskWriter.h
+++ b/src/MultiDiskWriter.h
@@ -36,16 +36,16 @@
#define _D_MULTI_DISK_WRITER_H_
#include "DefaultDiskWriter.h"
-#include "TorrentMan.h"
#include "messageDigest.h"
+#include "FileEntry.h"
class DiskWriterEntry {
public:
- FileEntry fileEntry;
+ FileEntryHandle fileEntry;
DiskWriter* diskWriter;
public:
- DiskWriterEntry(const FileEntry& fileEntry):fileEntry(fileEntry) {
- diskWriter = new DefaultDiskWriter(this->fileEntry.length);
+ DiskWriterEntry(const FileEntryHandle& fileEntry):fileEntry(fileEntry) {
+ diskWriter = new DefaultDiskWriter(this->fileEntry->getLength());
}
~DiskWriterEntry() {
delete diskWriter;
diff --git a/src/Peer.h b/src/Peer.h
index cc9fe26e..c7af34ee 100644
--- a/src/Peer.h
+++ b/src/Peer.h
@@ -75,11 +75,12 @@ private:
long long int sessionDownloadLength;
int pieceLength;
int latency;
+ bool active;
public:
- Peer(string ipaddr, int port, int pieceLength, long long int totalLength)
- :entryId(0), ipaddr(ipaddr), port(port), error(0),
+ Peer(string ipaddr, int port, int pieceLength, long long int totalLength):
+ entryId(0), ipaddr(ipaddr), port(port), error(0),
sessionUploadLength(0), sessionDownloadLength(0),
- pieceLength(pieceLength)
+ pieceLength(pieceLength), active(false)
{
resetStatus();
this->bitfield = new BitfieldMan(pieceLength, totalLength);
@@ -148,10 +149,16 @@ public:
void activate() {
peerStat.downloadStart();
+ active = true;
}
void deactivate() {
peerStat.downloadStop();
+ active = false;
+ }
+
+ bool isActive() const {
+ return active;
}
void setPeerId(const char* peerId) {
@@ -193,5 +200,6 @@ public:
};
typedef SharedHandle<Peer> PeerHandle;
+typedef deque<PeerHandle> Peers;
#endif // _D_PEER_H_
diff --git a/src/PeerAbstractCommand.cc b/src/PeerAbstractCommand.cc
index 6127450d..37e24c4e 100644
--- a/src/PeerAbstractCommand.cc
+++ b/src/PeerAbstractCommand.cc
@@ -41,23 +41,25 @@
PeerAbstractCommand::PeerAbstractCommand(int cuid, const PeerHandle& peer,
TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
const SocketHandle& s)
- :Command(cuid), e(e), socket(s), peer(peer),
- checkSocketIsReadable(false), checkSocketIsWritable(false),
- uploadLimitCheck(false), uploadLimit(0), noCheck(false) {
+ :BtContextAwareCommand(cuid, btContext), e(e), socket(s), peer(peer),
+ checkSocketIsReadable(false), checkSocketIsWritable(false),
+ uploadLimitCheck(false), uploadLimit(0), noCheck(false)
+{
setReadCheckSocket(socket);
timeout = e->option->getAsInt(PREF_TIMEOUT);
- e->torrentMan->connections++;
+ btRuntime->increaseConnections();
}
PeerAbstractCommand::~PeerAbstractCommand() {
disableReadCheckSocket();
disableWriteCheckSocket();
- e->torrentMan->connections--;
+ btRuntime->decreaseConnections();
}
bool PeerAbstractCommand::execute() {
- if(e->torrentMan->isHalt()) {
+ if(btRuntime->isHalt()) {
return true;
}
try {
diff --git a/src/PeerAbstractCommand.h b/src/PeerAbstractCommand.h
index 96573d81..52f25520 100644
--- a/src/PeerAbstractCommand.h
+++ b/src/PeerAbstractCommand.h
@@ -35,12 +35,12 @@
#ifndef _D_PEER_ABSTRACT_COMMAND_H_
#define _D_PEER_ABSTRACT_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "Request.h"
#include "TorrentDownloadEngine.h"
#include "TimeA2.h"
-class PeerAbstractCommand : public Command {
+class PeerAbstractCommand : public BtContextAwareCommand {
private:
Time checkPoint;
int timeout;
@@ -48,6 +48,7 @@ protected:
TorrentDownloadEngine* e;
SocketHandle socket;
PeerHandle peer;
+
void setTimeout(int timeout) { this->timeout = timeout; }
virtual bool prepareForNextPeer(int wait);
virtual bool prepareForRetry(int wait);
@@ -71,6 +72,7 @@ private:
public:
PeerAbstractCommand(int cuid, const PeerHandle& peer,
TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
const SocketHandle& s = SocketHandle());
virtual ~PeerAbstractCommand();
bool execute();
diff --git a/src/PeerChokeCommand.cc b/src/PeerChokeCommand.cc
index 4b0cd314..0b49b26d 100644
--- a/src/PeerChokeCommand.cc
+++ b/src/PeerChokeCommand.cc
@@ -35,7 +35,14 @@
#include "PeerChokeCommand.h"
#include "Util.h"
-PeerChokeCommand::PeerChokeCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), interval(interval), e(e), rotate(0) {}
+PeerChokeCommand::PeerChokeCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ int interval):
+ BtContextAwareCommand(cuid, btContext),
+ interval(interval),
+ e(e),
+ rotate(0) {}
PeerChokeCommand::~PeerChokeCommand() {}
@@ -89,14 +96,14 @@ void PeerChokeCommand::orderByDownloadRate(Peers& peers) const {
}
bool PeerChokeCommand::execute() {
- if(e->torrentMan->isHalt()) {
+ if(btRuntime->isHalt()) {
return true;
}
if(checkPoint.elapsed(interval)) {
checkPoint.reset();
- Peers peers = e->torrentMan->getActivePeers();
+ Peers peers = peerStorage->getActivePeers();
for_each(peers.begin(), peers.end(), ChokePeer());
- if(e->torrentMan->downloadComplete()) {
+ if(pieceStorage->downloadFinished()) {
orderByUploadRate(peers);
} else {
orderByDownloadRate(peers);
@@ -109,7 +116,7 @@ bool PeerChokeCommand::execute() {
peer->chokingRequired = false;
peer->optUnchoking = false;
itr = peers.erase(itr);
- if(e->torrentMan->downloadComplete()) {
+ if(pieceStorage->downloadFinished()) {
logger->debug("cat01, unchoking %s, upload speed=%d",
peer->ipaddr.c_str(),
peer->calculateUploadSpeed());
@@ -128,7 +135,7 @@ bool PeerChokeCommand::execute() {
peer->chokingRequired = false;
peer->optUnchoking = false;
itr = peers.erase(itr);
- if(e->torrentMan->downloadComplete()) {
+ if(pieceStorage->downloadFinished()) {
logger->debug("cat01, unchoking %s, upload speed=%d",
peer->ipaddr.c_str(),
peer->calculateUploadSpeed());
diff --git a/src/PeerChokeCommand.h b/src/PeerChokeCommand.h
index 8319a269..6b03ccac 100644
--- a/src/PeerChokeCommand.h
+++ b/src/PeerChokeCommand.h
@@ -35,11 +35,11 @@
#ifndef _D_PEER_CHOKE_COMMAND_H_
#define _D_PEER_CHOKE_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
#include "TimeA2.h"
-class PeerChokeCommand : public Command {
+class PeerChokeCommand : public BtContextAwareCommand {
private:
int interval;
TorrentDownloadEngine* e;
@@ -51,7 +51,11 @@ private:
void optUnchokingPeer(Peers& peers) const;
public:
- PeerChokeCommand(int cuid, TorrentDownloadEngine* e, int interval);
+ PeerChokeCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ int interval);
+
virtual ~PeerChokeCommand();
bool execute();
diff --git a/src/PeerConnection.h b/src/PeerConnection.h
index ab025ee9..de52f004 100644
--- a/src/PeerConnection.h
+++ b/src/PeerConnection.h
@@ -38,7 +38,6 @@
#include "Option.h"
#include "Socket.h"
#include "Logger.h"
-#include "TorrentMan.h"
#include "PeerMessage.h"
#include "common.h"
diff --git a/src/PeerInitiateConnectionCommand.cc b/src/PeerInitiateConnectionCommand.cc
index a578b40e..399cfb1e 100644
--- a/src/PeerInitiateConnectionCommand.cc
+++ b/src/PeerInitiateConnectionCommand.cc
@@ -41,8 +41,9 @@
PeerInitiateConnectionCommand::PeerInitiateConnectionCommand(int cuid,
const PeerHandle& peer,
- TorrentDownloadEngine* e)
- :PeerAbstractCommand(cuid, peer, e) {}
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext)
+ :PeerAbstractCommand(cuid, peer, e, btContext) {}
PeerInitiateConnectionCommand::~PeerInitiateConnectionCommand() {}
@@ -51,7 +52,13 @@ bool PeerInitiateConnectionCommand::executeInternal() {
logger->info(MSG_CONNECTING_TO_SERVER, cuid, peer->ipaddr.c_str(),
peer->port);
socket->establishConnection(peer->ipaddr, peer->port);
- command = new PeerInteractionCommand(cuid, peer, e, socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
+ command =
+ new PeerInteractionCommand(cuid,
+ peer,
+ e,
+ btContext,
+ socket,
+ PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
e->commands.push_back(command);
return true;
@@ -59,19 +66,26 @@ bool PeerInitiateConnectionCommand::executeInternal() {
// TODO this method removed when PeerBalancerCommand is implemented
bool PeerInitiateConnectionCommand::prepareForNextPeer(int wait) {
- if(e->torrentMan->isPeerAvailable()) {
- PeerHandle peer = e->torrentMan->getPeer();
- int newCuid = e->torrentMan->getNewCuid();
+ if(peerStorage->isPeerAvailable() && btRuntime->lessThanEqMinPeer()) {
+ PeerHandle peer = peerStorage->getUnusedPeer();
+ int newCuid = btRuntime->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command =
- new PeerInitiateConnectionCommand(newCuid, peer, e);
+ new PeerInitiateConnectionCommand(newCuid,
+ peer,
+ e,
+ btContext);
e->commands.push_back(command);
}
return true;
}
bool PeerInitiateConnectionCommand::prepareForRetry(int wait) {
- PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(cuid, peer, e);
+ PeerInitiateConnectionCommand* command =
+ new PeerInitiateConnectionCommand(cuid,
+ peer,
+ e,
+ btContext);
e->commands.push_back(command);
return true;
}
diff --git a/src/PeerInitiateConnectionCommand.h b/src/PeerInitiateConnectionCommand.h
index 15bad8d8..7a86f097 100644
--- a/src/PeerInitiateConnectionCommand.h
+++ b/src/PeerInitiateConnectionCommand.h
@@ -43,8 +43,11 @@ protected:
bool prepareForRetry(int wait);
bool prepareForNextPeer(int wait);
public:
- PeerInitiateConnectionCommand(int cuid, const PeerHandle& peer,
- TorrentDownloadEngine* e);
+ PeerInitiateConnectionCommand(int cuid,
+ const PeerHandle& peer,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext);
+
~PeerInitiateConnectionCommand();
};
diff --git a/src/PeerInteraction.cc b/src/PeerInteraction.cc
index 50e6fe86..1ec87ce0 100644
--- a/src/PeerInteraction.cc
+++ b/src/PeerInteraction.cc
@@ -39,20 +39,24 @@
#include "PeerMessageUtil.h"
#include "Util.h"
#include "prefs.h"
+#include "BtRegistry.h"
#include <netinet/in.h>
PeerInteraction::PeerInteraction(int cuid,
const PeerHandle& peer,
const SocketHandle& socket,
const Option* op,
- TorrentMan* torrentMan)
+ const BtContextHandle& btContext)
:cuid(cuid),
option(op),
- torrentMan(torrentMan),
+ btContext(btContext),
+ peerStorage(PEER_STORAGE(btContext)),
+ pieceStorage(PIECE_STORAGE(btContext)),
+ btAnnounce(BT_ANNOUNCE(btContext)),
peer(peer),
quickReplied(false) {
peerConnection = new PeerConnection(cuid, socket, op);
- peerMessageFactory = new PeerMessageFactory(cuid, this, peer);
+ peerMessageFactory = new PeerMessageFactory(cuid, btContext, this, peer);
logger = LogFactory::getInstance();
}
@@ -78,7 +82,7 @@ void PeerInteraction::sendMessages() {
PeerMessageHandle msg = messageQueue.front();
messageQueue.pop_front();
if(uploadLimit > 0) {
- TransferStat stat = torrentMan->calculateStat();
+ TransferStat stat = peerStorage->calculateStat();
if(uploadLimit < stat.uploadSpeed &&
msg->isUploading() && !msg->isInProgress()) {
tempQueue.push_back(msg);
@@ -155,7 +159,7 @@ void PeerInteraction::abortPiece(Piece& piece) {
itr++;
}
}
- torrentMan->cancelPiece(piece);
+ pieceStorage->cancelPiece(piece);
}
}
@@ -184,7 +188,7 @@ void PeerInteraction::checkRequestSlot() {
} else {
Piece piece = getDownloadPiece(slot.getIndex());
if(piece.hasBlock(slot.getBlockIndex()) ||
- torrentMan->hasPiece(piece.getIndex())) {
+ pieceStorage->hasPiece(piece.getIndex())) {
logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
" the block has been acquired.", cuid,
slot.getBlockIndex());
@@ -242,7 +246,7 @@ PeerMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
if(!quickReplied && quickReply && msgLength >= 48) {
quickReplied = true;
// check info_hash
- if(memcmp(torrentMan->getInfoHash(), &msg[28], INFO_HASH_LENGTH) == 0) {
+ if(memcmp(btContext->getInfoHash(), &msg[28], INFO_HASH_LENGTH) == 0) {
sendHandshake();
}
}
@@ -272,18 +276,18 @@ PeerMessageHandle PeerInteraction::receiveMessage() {
void PeerInteraction::syncPiece() {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
- torrentMan->syncPiece(*itr);
+ pieceStorage->syncPiece(*itr);
}
}
void PeerInteraction::updatePiece() {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
- torrentMan->updatePiece(*itr);
+ pieceStorage->updatePiece(*itr);
}
}
void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
- if(pieces.empty() && !torrentMan->hasMissingPiece(peer)) {
+ if(pieces.empty() && !pieceStorage->hasMissingPiece(peer)) {
if(peer->amInterested) {
logger->debug("CUID#%d - Not interested in the peer", cuid);
addMessage(peerMessageFactory->createNotInterestedMessage());
@@ -293,7 +297,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
onChoked();
if(peer->isFastExtensionEnabled()) {
while((int)pieces.size() < pieceNum) {
- Piece piece = torrentMan->getMissingFastPiece(peer);
+ Piece piece = pieceStorage->getMissingFastPiece(peer);
if(Piece::isNull(piece)) {
break;
} else {
@@ -303,7 +307,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
}
} else {
while((int)pieces.size() < pieceNum) {
- Piece piece = torrentMan->getMissingPiece(peer);
+ Piece piece = pieceStorage->getMissingPiece(peer);
if(Piece::isNull(piece)) {
break;
} else {
@@ -338,16 +342,16 @@ void PeerInteraction::addRequests() {
MAX_PENDING_REQUEST = 6;
}
int pieceNum;
- if(torrentMan->isEndGame()) {
+ if(pieceStorage->isEndGame()) {
pieceNum = 1;
} else {
- int blocks = DIV_FLOOR(torrentMan->pieceLength, BLOCK_LENGTH);
+ int blocks = DIV_FLOOR(btContext->getPieceLength(), BLOCK_LENGTH);
pieceNum = DIV_FLOOR(MAX_PENDING_REQUEST, blocks);
}
getNewPieceAndSendInterest(pieceNum);
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
Piece& piece = *itr;
- if(torrentMan->isEndGame()) {
+ if(pieceStorage->isEndGame()) {
BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
int count = countRequestSlot();
@@ -380,23 +384,23 @@ void PeerInteraction::addRequests() {
void PeerInteraction::sendHandshake() {
PeerMessageHandle handle =
- peerMessageFactory->createHandshakeMessage(torrentMan->getInfoHash(),
- torrentMan->peerId.c_str());
+ peerMessageFactory->createHandshakeMessage(btContext->getInfoHash(),
+ btAnnounce->getPeerId().c_str());
addMessage(handle);
sendMessages();
}
void PeerInteraction::sendBitfield() {
if(peer->isFastExtensionEnabled()) {
- if(torrentMan->hasAllPieces()) {
+ if(pieceStorage->downloadFinished()) {
addMessage(peerMessageFactory->createHaveAllMessage());
- } else if(torrentMan->getDownloadLength() > 0) {
+ } else if(pieceStorage->getCompletedLength() > 0) {
addMessage(peerMessageFactory->createBitfieldMessage());
} else {
addMessage(peerMessageFactory->createHaveNoneMessage());
}
} else {
- if(torrentMan->getDownloadLength() > 0) {
+ if(pieceStorage->getCompletedLength() > 0) {
addMessage(peerMessageFactory->createBitfieldMessage());
}
}
@@ -405,8 +409,10 @@ void PeerInteraction::sendBitfield() {
void PeerInteraction::sendAllowedFast() {
if(peer->isFastExtensionEnabled()) {
- Integers fastSet = Util::computeFastSet(peer->ipaddr, torrentMan->getInfoHash(),
- torrentMan->pieces, ALLOWED_FAST_SET_SIZE);
+ Integers fastSet = Util::computeFastSet(peer->ipaddr,
+ btContext->getInfoHash(),
+ btContext->getNumPieces(),
+ ALLOWED_FAST_SET_SIZE);
for(Integers::const_iterator itr = fastSet.begin();
itr != fastSet.end(); itr++) {
addMessage(peerMessageFactory->createAllowedFastMessage(*itr));
diff --git a/src/PeerInteraction.h b/src/PeerInteraction.h
index 342f99eb..ef62ba4d 100644
--- a/src/PeerInteraction.h
+++ b/src/PeerInteraction.h
@@ -37,9 +37,13 @@
#include "common.h"
#include "PeerConnection.h"
+#include "PeerMessageFactory.h"
#include "RequestSlot.h"
#include "SharedHandle.h"
-#include "PeerMessageFactory.h"
+#include "BtContext.h"
+#include "PeerStorage.h"
+#include "PieceStorage.h"
+#include "BtAnnounce.h"
#define REQUEST_TIME_OUT 60
#define ALLOWED_FAST_SET_SIZE 10
@@ -53,7 +57,10 @@ private:
RequestSlots requestSlots;
MessageQueue messageQueue;
const Option* option;
- TorrentMan* torrentMan;
+ BtContextHandle btContext;
+ PeerStorageHandle peerStorage;
+ PieceStorageHandle pieceStorage;
+ BtAnnounceHandle btAnnounce;
PeerConnection* peerConnection;
PeerHandle peer;
Pieces pieces;
@@ -70,7 +77,7 @@ public:
const PeerHandle& peer,
const SocketHandle& socket,
const Option* op,
- TorrentMan* torrentMan);
+ const BtContextHandle& btContext);
~PeerInteraction();
void addMessage(const PeerMessageHandle& peerMessage);
@@ -89,16 +96,20 @@ public:
int countMessageInQueue() const;
- TorrentMan* getTorrentMan() const { return torrentMan; }
+ BtContextHandle getBtContext() const { return btContext; }
+
PeerConnection* getPeerConnection() const { return peerConnection; }
+
// If this object has nullPiece, then return false, otherwise true
bool hasDownloadPiece(int index) const;
+
// If the piece which this object has is nullPiece, then throws an exception.
// So before calling this function, call hasDownloadPiece and make sure
// this has valid piece, not nullPiece.
Piece& getDownloadPiece(int index);
bool isInFastSet(int index) const;
+
void addFastSetIndex(int index);
void syncPiece();
diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc
index 30d934d9..86a6c3cd 100644
--- a/src/PeerInteractionCommand.cc
+++ b/src/PeerInteractionCommand.cc
@@ -49,26 +49,27 @@
PeerInteractionCommand::PeerInteractionCommand(int cuid,
const PeerHandle& p,
TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
const SocketHandle& s,
int sequence)
- :PeerAbstractCommand(cuid, p, e, s), sequence(sequence) {
+ :PeerAbstractCommand(cuid, p, e, btContext, s), sequence(sequence) {
if(sequence == INITIATOR_SEND_HANDSHAKE) {
disableReadCheckSocket();
setWriteCheckSocket(socket);
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
}
peerInteraction = new PeerInteraction(cuid, peer, socket, e->option,
- e->torrentMan);
+ btContext);
setUploadLimit(e->option->getAsInt(PREF_MAX_UPLOAD_LIMIT));
chokeUnchokeCount = 0;
haveCount = 0;
keepAliveCount = 0;
- e->torrentMan->addActivePeer(peer);
+ peer->activate();
}
PeerInteractionCommand::~PeerInteractionCommand() {
delete peerInteraction;
- e->torrentMan->deleteActivePeer(peer);
+ peer->deactivate();
}
bool PeerInteractionCommand::executeInternal() {
@@ -173,7 +174,7 @@ void PeerInteractionCommand::detectMessageFlooding() {
/*
void PeerInteractionCommand::checkLongTimePeerChoking() {
- if(e->torrentMan->downloadComplete()) {
+ if(pieceStorage->downloadFinished()) {
return;
}
if(peer->amInterested && peer->peerChoking) {
@@ -205,7 +206,7 @@ void PeerInteractionCommand::receiveMessages() {
for(int i = 0; i < 50; i++) {
int maxSpeedLimit = e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT);
if(maxSpeedLimit > 0) {
- TransferStat stat = e->torrentMan->calculateStat();
+ TransferStat stat = peerStorage->calculateStat();
if(maxSpeedLimit < stat.downloadSpeed) {
disableReadCheckSocket();
setNoCheck(true);
@@ -245,12 +246,15 @@ void PeerInteractionCommand::receiveMessages() {
// TODO this method removed when PeerBalancerCommand is implemented
bool PeerInteractionCommand::prepareForNextPeer(int wait) {
- if(e->torrentMan->isPeerAvailable()) {
- PeerHandle peer = e->torrentMan->getPeer();
- int newCuid = e->torrentMan->getNewCuid();
+ if(peerStorage->isPeerAvailable() && btRuntime->lessThanEqMinPeer()) {
+ PeerHandle peer = peerStorage->getUnusedPeer();
+ int newCuid = btRuntime->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command =
- new PeerInitiateConnectionCommand(newCuid, peer, e);
+ new PeerInitiateConnectionCommand(newCuid,
+ peer,
+ e,
+ btContext);
e->commands.push_back(command);
}
return true;
@@ -278,12 +282,12 @@ void PeerInteractionCommand::sendKeepAlive() {
}
void PeerInteractionCommand::checkHave() {
- PieceIndexes indexes =
- e->torrentMan->getAdvertisedPieceIndexes(cuid, haveCheckTime);
+ Integers indexes =
+ pieceStorage->getAdvertisedPieceIndexes(cuid, haveCheckTime);
haveCheckTime.reset();
if(indexes.size() >= 20) {
if(peer->isFastExtensionEnabled()) {
- if(e->torrentMan->hasAllPieces()) {
+ if(pieceStorage->downloadFinished()) {
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createHaveAllMessage());
} else {
@@ -295,7 +299,7 @@ void PeerInteractionCommand::checkHave() {
createBitfieldMessage());
}
} else {
- for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
+ for(Integers::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createHaveMessage(*itr));
}
diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h
index 5b0e65cf..73b9fc54 100644
--- a/src/PeerInteractionCommand.h
+++ b/src/PeerInteractionCommand.h
@@ -73,7 +73,9 @@ protected:
public:
PeerInteractionCommand(int cuid, const PeerHandle& peer,
TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
const SocketHandle& s, int sequence);
+
~PeerInteractionCommand();
enum Seq {
diff --git a/src/PeerListProcessor.h b/src/PeerListProcessor.h
index 617042af..7a235641 100644
--- a/src/PeerListProcessor.h
+++ b/src/PeerListProcessor.h
@@ -40,8 +40,6 @@
#include "Peer.h"
#include "SharedHandle.h"
-typedef deque<PeerHandle> Peers;
-
class PeerListProcessor {
public:
virtual ~PeerListProcessor() {}
diff --git a/src/PeerListenCommand.cc b/src/PeerListenCommand.cc
index ae9bfd9b..d7808127 100644
--- a/src/PeerListenCommand.cc
+++ b/src/PeerListenCommand.cc
@@ -35,8 +35,11 @@
#include "PeerListenCommand.h"
#include "PeerInteractionCommand.h"
-PeerListenCommand::PeerListenCommand(int cuid, TorrentDownloadEngine* e)
- :Command(cuid), e(e) {}
+PeerListenCommand::PeerListenCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext)
+ :BtContextAwareCommand(cuid, btContext),
+ e(e) {}
PeerListenCommand::~PeerListenCommand() {}
@@ -61,7 +64,7 @@ int PeerListenCommand::bindPort(int portRangeStart, int portRangeEnd) {
}
bool PeerListenCommand::execute() {
- if(e->torrentMan->isHalt()) {
+ if(btRuntime->isHalt()) {
return true;
}
for(int i = 0; i < 3 && socket->isReadable(0); i++) {
@@ -73,15 +76,17 @@ bool PeerListenCommand::execute() {
pair<string, int> localInfo;
peerSocket->getAddrInfo(localInfo);
if(peerInfo.first != localInfo.first &&
- e->torrentMan->connections < MAX_PEERS) {
+ btRuntime->getConnections() < MAX_PEERS) {
PeerHandle peer = PeerHandle(new Peer(peerInfo.first, peerInfo.second,
- e->torrentMan->pieceLength,
- e->torrentMan->getTotalLength()));
- if(e->torrentMan->addPeer(peer)) {
- int newCuid = e->torrentMan->getNewCuid();
+ btContext->getPieceLength(),
+ btContext->getTotalLength()));
+ if(peerStorage->addPeer(peer)) {
+ int newCuid = btRuntime->getNewCuid();
peer->cuid = newCuid;
PeerInteractionCommand* command =
- new PeerInteractionCommand(newCuid, peer, e, peerSocket,
+ new PeerInteractionCommand(newCuid, peer, e,
+ btContext,
+ peerSocket,
PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE);
e->commands.push_back(command);
logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid);
diff --git a/src/PeerListenCommand.h b/src/PeerListenCommand.h
index a83c1e01..1ae2de91 100644
--- a/src/PeerListenCommand.h
+++ b/src/PeerListenCommand.h
@@ -35,15 +35,18 @@
#ifndef _D_PEER_LISTEN_COMMAND_H_
#define _D_PEER_LISTEN_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
-class PeerListenCommand : public Command {
+class PeerListenCommand : public BtContextAwareCommand {
private:
TorrentDownloadEngine* e;
SocketHandle socket;
public:
- PeerListenCommand(int cuid, TorrentDownloadEngine* e);
+ PeerListenCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext);
+
~PeerListenCommand();
bool execute();
diff --git a/src/PeerMessage.cc b/src/PeerMessage.cc
index d7a16ff2..fe440668 100644
--- a/src/PeerMessage.cc
+++ b/src/PeerMessage.cc
@@ -38,6 +38,10 @@
PeerMessage::PeerMessage()
:inProgress(false),
invalidate(false),
- uploading(false) {
+ uploading(false),
+ btContext(0),
+ peerStorage(0),
+ pieceStorage(0)
+ {
logger = LogFactory::getInstance();
}
diff --git a/src/PeerMessage.h b/src/PeerMessage.h
index 0ef772ff..2d54646b 100644
--- a/src/PeerMessage.h
+++ b/src/PeerMessage.h
@@ -39,7 +39,10 @@
#include "Logger.h"
#include "Peer.h"
#include "Piece.h"
-#include "SharedHandle.h"
+#include "BtContext.h"
+#include "PeerStorage.h"
+#include "PieceStorage.h"
+#include "BtRegistry.h"
#include <string>
class PeerInteraction;
@@ -53,6 +56,9 @@ protected:
PeerHandle peer;
PeerInteraction* peerInteraction;
const Logger* logger;
+ BtContextHandle btContext;
+ PeerStorageHandle peerStorage;
+ PieceStorageHandle pieceStorage;
public:
PeerMessage();
@@ -63,18 +69,29 @@ public:
bool isUploading() const { return uploading; }
int getCuid() const { return cuid; }
+
void setCuid(int cuid) {
this->cuid = cuid;
}
+
PeerHandle getPeer() const { return this->peer; }
+
void setPeer(const PeerHandle& peer) {
this->peer = peer;
}
+
PeerInteraction* getPeerInteraction() const { return peerInteraction; }
+
void setPeerInteraction(PeerInteraction* peerInteraction) {
this->peerInteraction = peerInteraction;
}
+ void setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ pieceStorage = PIECE_STORAGE(btContext);
+ peerStorage = PEER_STORAGE(btContext);
+ }
+
virtual int getId() const = 0;
virtual void receivedAction() = 0;
virtual void send() = 0;
diff --git a/src/PeerMessageFactory.cc b/src/PeerMessageFactory.cc
index 1c031075..95709c8e 100644
--- a/src/PeerMessageFactory.cc
+++ b/src/PeerMessageFactory.cc
@@ -33,7 +33,6 @@
*/
/* copyright --> */
#include "PeerMessageFactory.h"
-#include "PeerInteraction.h"
#include "PeerMessageUtil.h"
#include "ChokeMessage.h"
#include "UnchokeMessage.h"
@@ -54,11 +53,16 @@
#include "SuggestPieceMessage.h"
#include "RequestSlot.h"
#include "DlAbortEx.h"
+#include "BtRegistry.h"
+#include "PeerInteraction.h"
PeerMessageFactory::PeerMessageFactory(int cuid,
+ const BtContextHandle& btContext,
PeerInteraction* peerInteraction,
const PeerHandle& peer)
:cuid(cuid),
+ btContext(btContext),
+ pieceStorage(PIECE_STORAGE(btContext)),
peerInteraction(peerInteraction),
peer(peer) {}
@@ -86,29 +90,26 @@ PeerMessageHandle PeerMessageFactory::createPeerMessage(const char* msg, int msg
break;
case HaveMessage::ID:
peerMessage = HaveMessage::create(msg, msgLength);
- ((HaveMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->
- pieces);
+ ((HaveMessage*)peerMessage)->setPieces(btContext->getNumPieces());
break;
case BitfieldMessage::ID:
peerMessage = BitfieldMessage::create(msg, msgLength);
- ((BitfieldMessage*)peerMessage)->setPieces(peerInteraction->
- getTorrentMan()->pieces);
+ ((BitfieldMessage*)peerMessage)->setPieces(btContext->getNumPieces());
break;
case RequestMessage::ID:
peerMessage = RequestMessage::create(msg, msgLength);
- ((RequestMessage*)peerMessage)->setPieces(peerInteraction->
- getTorrentMan()->pieces);
- ((RequestMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
+ ((RequestMessage*)peerMessage)->setPieces(btContext->getNumPieces());
+ ((RequestMessage*)peerMessage)->setPieceLength(pieceStorage->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
break;
case CancelMessage::ID:
peerMessage = CancelMessage::create(msg, msgLength);
- ((CancelMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
- ((CancelMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
+ ((CancelMessage*)peerMessage)->setPieces(btContext->getNumPieces());
+ ((CancelMessage*)peerMessage)->setPieceLength(pieceStorage->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
break;
case PieceMessage::ID:
peerMessage = PieceMessage::create(msg, msgLength);
- ((PieceMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
- ((PieceMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
+ ((PieceMessage*)peerMessage)->setPieces(btContext->getNumPieces());
+ ((PieceMessage*)peerMessage)->setPieceLength(pieceStorage->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
break;
case PortMessage::ID:
peerMessage = PortMessage::create(msg, msgLength);
@@ -121,16 +122,16 @@ PeerMessageHandle PeerMessageFactory::createPeerMessage(const char* msg, int msg
break;
case RejectMessage::ID:
peerMessage = RejectMessage::create(msg, msgLength);
- ((RejectMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
- ((RejectMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
+ ((RejectMessage*)peerMessage)->setPieces(btContext->getNumPieces());
+ ((RejectMessage*)peerMessage)->setPieceLength(pieceStorage->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
break;
case SuggestPieceMessage::ID:
peerMessage = SuggestPieceMessage::create(msg, msgLength);
- ((SuggestPieceMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+ ((SuggestPieceMessage*)peerMessage)->setPieces(btContext->getNumPieces());
break;
case AllowedFastMessage::ID:
peerMessage = AllowedFastMessage::create(msg, msgLength);
- ((AllowedFastMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+ ((AllowedFastMessage*)peerMessage)->setPieces(btContext->getNumPieces());
break;
default:
throw new DlAbortEx("Invalid message id. id = %d", id);
@@ -167,6 +168,7 @@ PeerMessageFactory::setPeerMessageCommonProperty(PeerMessageHandle& peerMessage)
peerMessage->setPeer(peer);
peerMessage->setCuid(cuid);
peerMessage->setPeerInteraction(peerInteraction);
+ peerMessage->setBtContext(btContext);
}
PeerMessageHandle PeerMessageFactory::createRequestMessage(const Piece& piece,
@@ -235,10 +237,8 @@ PeerMessageHandle PeerMessageFactory::createNotInterestedMessage() const {
PeerMessageHandle PeerMessageFactory::createBitfieldMessage() const {
PeerMessageHandle handle =
- PeerMessageHandle(new BitfieldMessage(peerInteraction->getTorrentMan()->
- getBitfield(),
- peerInteraction->getTorrentMan()->
- getBitfieldLength()));
+ PeerMessageHandle(new BitfieldMessage(pieceStorage->getBitfield(),
+ pieceStorage->getBitfieldLength()));
setPeerMessageCommonProperty(handle);
return handle;
}
diff --git a/src/PeerMessageFactory.h b/src/PeerMessageFactory.h
index 147be5c4..481a0b31 100644
--- a/src/PeerMessageFactory.h
+++ b/src/PeerMessageFactory.h
@@ -38,18 +38,23 @@
#include "common.h"
#include "PeerMessage.h"
#include "HandshakeMessage.h"
+#include "BtContext.h"
+#include "PieceStorage.h"
class PeerInteraction;
class PeerMessageFactory {
private:
int cuid;
+ BtContextHandle btContext;
+ PieceStorageHandle pieceStorage;
PeerInteraction* peerInteraction;
PeerHandle peer;
void setPeerMessageCommonProperty(PeerMessageHandle& peerMessage) const;
public:
PeerMessageFactory(int cuid,
+ const BtContextHandle& btContext,
PeerInteraction* peerInteraction,
const PeerHandle& peer);
diff --git a/src/PeerStorage.h b/src/PeerStorage.h
new file mode 100644
index 00000000..c5bc49e4
--- /dev/null
+++ b/src/PeerStorage.h
@@ -0,0 +1,128 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_PEER_STORAGE_H_
+#define _D_PEER_STORAGE_H_
+
+#include "common.h"
+#include "Peer.h"
+
+class TransferStat {
+public:
+ int downloadSpeed;
+ int uploadSpeed;
+ long long int sessionDownloadLength;
+ long long int sessionUploadLength;
+public:
+ TransferStat():downloadSpeed(0), uploadSpeed(0),
+ sessionDownloadLength(0), sessionUploadLength(0) {}
+
+ int getDownloadSpeed() const {
+ return downloadSpeed;
+ }
+
+ void setDownloadSpeed(int s) { downloadSpeed = s; }
+
+ int getUploadSpeed() const {
+ return uploadSpeed;
+ }
+
+ void setUploadSpeed(int s) { uploadSpeed = s; }
+
+ /**
+ * Returns the number of bytes downloaded since the program started.
+ * This is not the total number of bytes downloaded.
+ */
+ long long int getSessionDownloadLength() const {
+ return sessionDownloadLength;
+ }
+
+ void setSessionDownloadLength(long long int s) { sessionDownloadLength = s; }
+
+ /**
+ * Returns the number of bytes uploaded since the program started.
+ * This is not the total number of bytes uploaded.
+ */
+ long long int getSessionUploadLength() const {
+ return sessionUploadLength;
+ }
+
+ void setSessionUploadLength(long long int s) { sessionUploadLength = s; }
+};
+
+class PeerStorage {
+public:
+ virtual ~PeerStorage() {}
+
+ /**
+ * Adds new peer to internal peer list.
+ * If the peer is added successfully, returns true. Otherwise returns false.
+ */
+ virtual bool addPeer(const PeerHandle& peer) = 0;
+
+ /**
+ * Adds all peers in peers to internal peer list.
+ */
+ virtual void addPeer(const Peers& peers) = 0;
+
+ /**
+ * Returns internal peer list.
+ */
+ virtual const Peers& getPeers() = 0;
+
+ /**
+ * Returns one of the unused peers.
+ */
+ virtual PeerHandle getUnusedPeer() = 0;
+
+ /**
+ * Returns true if at least one unused peer exists.
+ * Otherwise returns false.
+ */
+ virtual bool isPeerAvailable() = 0;
+
+ /**
+ * Returns the list of peers which are currently connected from localhost.
+ */
+ virtual Peers getActivePeers() = 0;
+
+ /**
+ * Calculates current download/upload statistics.
+ */
+ virtual TransferStat calculateStat() = 0;
+};
+
+typedef SharedHandle<PeerStorage> PeerStorageHandle;
+
+#endif // _D_PEER_STORAGE_H_
diff --git a/src/Piece.cc b/src/Piece.cc
index 900a4a96..f8d5ed68 100644
--- a/src/Piece.cc
+++ b/src/Piece.cc
@@ -33,6 +33,7 @@
*/
/* copyright --> */
#include "Piece.h"
+#include "Util.h"
Piece Piece::nullPiece;
@@ -79,3 +80,7 @@ int Piece::getMissingBlockIndex() const {
BlockIndexes Piece::getAllMissingBlockIndexes() const {
return bitfield->getAllMissingIndexes();
}
+
+string Piece::toString() const {
+ return "piece: index="+Util::itos(index)+", length="+Util::itos(length);
+}
diff --git a/src/Piece.h b/src/Piece.h
index 4a7c2a6a..f18eae38 100644
--- a/src/Piece.h
+++ b/src/Piece.h
@@ -117,10 +117,14 @@ public:
void clearAllBlock();
void setAllBlock();
+ string toString() const;
+
static Piece nullPiece;
static bool isNull(const Piece& piece) {
return piece.index == 0 && piece.length == 0;
}
};
+typedef deque<Piece> Pieces;
+
#endif // _D_PIECE_H_
diff --git a/src/PieceMessage.cc b/src/PieceMessage.cc
index 4c1f414c..367ad2f9 100644
--- a/src/PieceMessage.cc
+++ b/src/PieceMessage.cc
@@ -65,7 +65,6 @@ PieceMessage* PieceMessage::create(const char* data, int dataLength) {
}
void PieceMessage::receivedAction() {
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
RequestSlot slot = peerInteraction->getCorrespondingRequestSlot(index,
begin,
blockLength);
@@ -77,15 +76,15 @@ void PieceMessage::receivedAction() {
peer->updateLatency(slot.getLatencyInMillis());
Piece& piece = peerInteraction->getDownloadPiece(slot.getIndex());
long long int offset =
- ((long long int)index)*torrentMan->pieceLength+begin;
+ ((long long int)index)*btContext->getPieceLength()+begin;
logger->debug("CUID#%d - Writing the block length=%d, offset=%lld",
cuid, blockLength, offset);
- torrentMan->diskAdaptor->writeData(block,
- blockLength,
- offset);
+ pieceStorage->getDiskAdaptor()->writeData(block,
+ blockLength,
+ offset);
piece.completeBlock(slot.getBlockIndex());
peerInteraction->deleteRequestSlot(slot);
- torrentMan->updatePiece(piece);
+ pieceStorage->updatePiece(piece);
logger->debug("CUID#%d - Setting piece block index=%d",
cuid, slot.getBlockIndex());
if(piece.pieceComplete()) {
@@ -123,7 +122,6 @@ void PieceMessage::send() {
if(invalidate) {
return;
}
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
PeerConnection* peerConnection = peerInteraction->getPeerConnection();
if(!headerSent) {
if(!inProgress) {
@@ -146,13 +144,11 @@ void PieceMessage::send() {
}
if(headerSent) {
inProgress = false;
- int pieceLength = torrentMan->pieceLength;
long long int pieceDataOffset =
- ((long long int)index)*pieceLength+begin+blockLength-leftDataLength;
+ ((long long int)index)*btContext->getPieceLength()+begin+blockLength-leftDataLength;
int writtenLength =
sendPieceData(pieceDataOffset, leftDataLength);
peer->updateUploadLength(writtenLength);
- torrentMan->addUploadLength(writtenLength);
if(writtenLength != leftDataLength) {
inProgress = true;
}
@@ -165,10 +161,9 @@ int PieceMessage::sendPieceData(long long int offset, int length) const {
char buf[BUF_SIZE];
int iteration = length/BUF_SIZE;
int writtenLength = 0;
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
PeerConnection* peerConnection = peerInteraction->getPeerConnection();
for(int i = 0; i < iteration; i++) {
- if(torrentMan->diskAdaptor->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
+ if(pieceStorage->getDiskAdaptor()->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
throw new DlAbortEx("Failed to read data from disk.");
}
int ws = peerConnection->sendMessage(buf, BUF_SIZE);
@@ -181,7 +176,7 @@ int PieceMessage::sendPieceData(long long int offset, int length) const {
int rem = length%BUF_SIZE;
if(rem > 0) {
- if(torrentMan->diskAdaptor->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
+ if(pieceStorage->getDiskAdaptor()->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
throw new DlAbortEx("Failed to read data from disk.");
}
int ws = peerConnection->sendMessage(buf, rem);
@@ -202,42 +197,39 @@ string PieceMessage::toString() const {
}
bool PieceMessage::checkPieceHash(const Piece& piece) {
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
long long int offset =
- ((long long int)piece.getIndex())*torrentMan->pieceLength;
- return torrentMan->diskAdaptor->sha1Sum(offset, piece.getLength()) ==
- torrentMan->getPieceHash(piece.getIndex());
+ ((long long int)piece.getIndex())*btContext->getPieceLength();
+ return pieceStorage->getDiskAdaptor()->sha1Sum(offset, piece.getLength()) ==
+ btContext->getPieceHash(piece.getIndex());
}
void PieceMessage::onGotNewPiece(Piece& piece) {
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
logger->info(MSG_GOT_NEW_PIECE, cuid, piece.getIndex());
- torrentMan->completePiece(piece);
- torrentMan->advertisePiece(cuid, piece.getIndex());
+ pieceStorage->completePiece(piece);
+ pieceStorage->advertisePiece(cuid, piece.getIndex());
}
void PieceMessage::onGotWrongPiece(Piece& piece) {
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
logger->error(MSG_GOT_WRONG_PIECE, cuid, piece.getIndex());
erasePieceOnDisk(piece);
piece.clearAllBlock();
- torrentMan->updatePiece(piece);
+ pieceStorage->updatePiece(piece);
peerInteraction->abortPiece(piece);
}
void PieceMessage::erasePieceOnDisk(const Piece& piece) {
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
int BUFSIZE = 4096;
char buf[BUFSIZE];
memset(buf, 0, BUFSIZE);
- long long int offset = ((long long int)piece.getIndex())*torrentMan->pieceLength;
+ long long int offset =
+ ((long long int)piece.getIndex())*btContext->getPieceLength();
for(int i = 0; i < piece.getLength()/BUFSIZE; i++) {
- torrentMan->diskAdaptor->writeData(buf, BUFSIZE, offset);
+ pieceStorage->getDiskAdaptor()->writeData(buf, BUFSIZE, offset);
offset += BUFSIZE;
}
int r = piece.getLength()%BUFSIZE;
if(r > 0) {
- torrentMan->diskAdaptor->writeData(buf, r, offset);
+ pieceStorage->getDiskAdaptor()->writeData(buf, r, offset);
}
}
diff --git a/src/PieceMessage.h b/src/PieceMessage.h
index 90f5b0b7..328ff7bd 100644
--- a/src/PieceMessage.h
+++ b/src/PieceMessage.h
@@ -36,7 +36,6 @@
#define _D_PIECE_MESSAGE_H_
#include "PeerMessage.h"
-#include "TorrentMan.h"
class PieceMessage : public PeerMessage {
private:
diff --git a/src/PieceStorage.h b/src/PieceStorage.h
new file mode 100644
index 00000000..4ee76e05
--- /dev/null
+++ b/src/PieceStorage.h
@@ -0,0 +1,157 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_PIECE_STORAGE_H_
+#define _D_PIECE_STORAGE_H_
+
+#include "common.h"
+#include "Peer.h"
+#include "Piece.h"
+#include "DiskAdaptor.h"
+
+class PieceStorage {
+public:
+ virtual ~PieceStorage() {}
+
+ /**
+ * Returns true if the peer has a piece that localhost doesn't have.
+ * Otherwise returns false.
+ */
+ virtual bool hasMissingPiece(const PeerHandle& peer) = 0;
+
+ /**
+ * Returns a piece that the peer has but localhost doesn't.
+ * The piece will be marked "used" status in order to prevent other command
+ * from get the same piece. But in end game mode, same piece may be returned
+ * to several commands.
+ */
+ virtual Piece getMissingPiece(const PeerHandle& peer) = 0;
+ /**
+ * Returns a piece that the peer has but localhost doesn't.
+ * Only pieces that declared as "fast" are returned.
+ * The piece will be marked "used" status in order to prevent other command
+ * from get the same piece. But in end game mode, same piece may be returned
+ * to several commands.
+ */
+ virtual Piece getMissingFastPiece(const PeerHandle& peer) = 0;
+
+ /**
+ * Tells that the download of the specfied piece completes.
+ */
+ virtual void completePiece(const Piece& piece) = 0;
+
+ /**
+ * Tells that the download of the specified piece is canceled.
+ */
+ virtual void cancelPiece(const Piece& piece) = 0;
+
+ /**
+ * Updates the internal piece data with the specified piece data.
+ */
+ virtual void updatePiece(const Piece& piece) = 0;
+
+ /**
+ * Updates the spcefied piece data with the internal piece data.
+ */
+ virtual void syncPiece(Piece& piece) = 0;
+
+ /**
+ * Returns true if the specified piece is already downloaded.
+ * Otherwise returns false.
+ */
+ virtual bool hasPiece(int index) = 0;
+
+ virtual long long int getTotalLength() = 0;
+
+ virtual long long int getFilteredTotalLength() = 0;
+
+ virtual long long int getCompletedLength() = 0;
+
+ virtual long long int getFilteredCompletedLength() = 0;
+
+ virtual void setFileFilter(const Strings& filePaths) = 0;
+
+ virtual void setFileFilter(const Integers& fileIndexes) = 0;
+
+ virtual void clearFileFilter() = 0;
+
+ virtual bool downloadFinished() = 0;
+
+ /**
+ * Initializes DiskAdaptor.
+ * TODO add better documentation here.
+ */
+ virtual void initStorage() = 0;
+
+ virtual const unsigned char* getBitfield() = 0;
+
+ virtual void setBitfield(const unsigned char* bitfield,
+ int bitfieldLength) = 0;
+
+ virtual int getBitfieldLength() = 0;
+
+ virtual bool isSelectiveDownloadingMode() = 0;
+
+ virtual void finishSelectiveDownloadingMode() = 0;
+
+ virtual bool isEndGame() = 0;
+
+ virtual DiskAdaptor* getDiskAdaptor() = 0;
+
+ virtual int getPieceLength(int index) = 0;
+
+ /**
+ * Adds piece index to advertise to other commands. They send have message
+ * based on this information.
+ */
+ virtual void advertisePiece(int cuid, int index) = 0;
+
+ /**
+ * Returns piece index which is not advertised by the caller command and
+ * newer than lastCheckTime.
+ */
+ virtual Integers getAdvertisedPieceIndexes(int myCuid,
+ const Time& lastCheckTime) = 0;
+
+ /**
+ * Removes have entry if specified seconds have elapsed since its
+ * registration.
+ */
+ virtual void removeAdvertisedPiece(int elapsed) = 0;
+
+};
+
+typedef SharedHandle<PieceStorage> PieceStorageHandle;
+
+#endif // _D_PIECE_STORAGE_H_
diff --git a/src/RejectMessage.h b/src/RejectMessage.h
index 7d2b43cf..5b33d37e 100644
--- a/src/RejectMessage.h
+++ b/src/RejectMessage.h
@@ -36,7 +36,6 @@
#define _D_REJECT_MESSAGE_H_
#include "SimplePeerMessage.h"
-#include "TorrentMan.h"
class RejectMessage : public SimplePeerMessage {
private:
diff --git a/src/RequestMessage.cc b/src/RequestMessage.cc
index 62c68427..0ab6e343 100644
--- a/src/RequestMessage.cc
+++ b/src/RequestMessage.cc
@@ -55,8 +55,7 @@ RequestMessage* RequestMessage::create(const char* data, int dataLength) {
}
void RequestMessage::receivedAction() {
- TorrentMan* torrentMan = peerInteraction->getTorrentMan();
- if(torrentMan->hasPiece(index) &&
+ if(pieceStorage->hasPiece(index) &&
(!peer->amChoking ||
peer->amChoking && peerInteraction->isInFastSet(index))) {
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
diff --git a/src/RequestMessage.h b/src/RequestMessage.h
index 68d20d77..7c7c7b20 100644
--- a/src/RequestMessage.h
+++ b/src/RequestMessage.h
@@ -36,7 +36,6 @@
#define _D_REQUEST_MESSAGE_H_
#include "SimplePeerMessage.h"
-#include "TorrentMan.h"
class RequestMessage : public SimplePeerMessage {
private:
diff --git a/src/SeedCheckCommand.cc b/src/SeedCheckCommand.cc
index 51de429d..ae869724 100644
--- a/src/SeedCheckCommand.cc
+++ b/src/SeedCheckCommand.cc
@@ -34,8 +34,17 @@
/* copyright --> */
#include "SeedCheckCommand.h"
+SeedCheckCommand::SeedCheckCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ SeedCriteriaHandle seedCriteria)
+ :BtContextAwareCommand(cuid, btContext),
+ e(e),
+ seedCriteria(seedCriteria),
+ checkStarted(false) {}
+
bool SeedCheckCommand::execute() {
- if(e->torrentMan->isHalt()) {
+ if(btRuntime->isHalt()) {
return true;
}
if(!seedCriteria.get()) {
@@ -43,7 +52,7 @@ bool SeedCheckCommand::execute() {
}
if(checkPoint.elapsed(1)) {
if(!checkStarted) {
- if(e->torrentMan->downloadComplete()) {
+ if(pieceStorage->downloadFinished()) {
checkStarted = true;
seedCriteria->reset();
}
@@ -51,7 +60,7 @@ bool SeedCheckCommand::execute() {
if(checkStarted) {
if(seedCriteria->evaluate()) {
logger->notice("CUID#%d - Seeding is over.", cuid);
- e->torrentMan->setHalt(true);
+ btRuntime->setHalt(true);
}
}
}
diff --git a/src/SeedCheckCommand.h b/src/SeedCheckCommand.h
index 5e4f92bb..4ade4094 100644
--- a/src/SeedCheckCommand.h
+++ b/src/SeedCheckCommand.h
@@ -35,24 +35,22 @@
#ifndef _D_SEED_CHECK_COMMAND_H_
#define _D_SEED_CHECK_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
#include "TimeA2.h"
#include "SeedCriteria.h"
-class SeedCheckCommand : public Command {
+class SeedCheckCommand : public BtContextAwareCommand {
private:
TorrentDownloadEngine* e;
Time checkPoint;
SeedCriteriaHandle seedCriteria;
bool checkStarted;
public:
- SeedCheckCommand(int cuid, TorrentDownloadEngine* e,
- SeedCriteriaHandle seedCriteria)
- :Command(cuid),
- e(e),
- seedCriteria(seedCriteria),
- checkStarted(false) {}
+ SeedCheckCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ SeedCriteriaHandle seedCriteria);
virtual ~SeedCheckCommand() {}
diff --git a/src/ShareRatioSeedCriteria.h b/src/ShareRatioSeedCriteria.h
index 72f32227..6ded3b02 100644
--- a/src/ShareRatioSeedCriteria.h
+++ b/src/ShareRatioSeedCriteria.h
@@ -36,26 +36,37 @@
#define _D_SHARE_RATIO_SEED_CRITERIA_H_
#include "SeedCriteria.h"
-#include "TorrentMan.h"
+#include "BtContext.h"
+#include "PeerStorage.h"
+#include "BtRuntime.h"
+#include "BtRegistry.h"
class ShareRatioSeedCriteria : public SeedCriteria {
private:
double ratio;
- TorrentMan* torrentMan;
+ BtContextHandle btContext;
+ PeerStorageHandle peerStorage;
+ BtRuntimeHandle btRuntime;
public:
- ShareRatioSeedCriteria(double ratio, TorrentMan* torrentMan)
+ ShareRatioSeedCriteria(double ratio, const BtContextHandle& btContext)
:ratio(ratio),
- torrentMan(torrentMan) {}
+ btContext(btContext),
+ peerStorage(PEER_STORAGE(btContext)),
+ btRuntime(BT_RUNTIME(btContext)) {}
+
virtual ~ShareRatioSeedCriteria() {}
virtual void reset() {}
virtual bool evaluate() {
- if(torrentMan->getDownloadLength() == 0) {
+ if(btContext->getTotalLength() == 0) {
return false;
}
+ TransferStat stat = peerStorage->calculateStat();
+ long long int allTimeUploadLength =
+ btRuntime->getUploadLengthAtStartup()+stat.getSessionUploadLength();
return ratio <=
- ((double)torrentMan->getUploadLength())/torrentMan->getDownloadLength();
+ ((double)allTimeUploadLength)/btContext->getTotalLength();
}
void setRatio(double ratio) {
diff --git a/src/TorrentAutoSaveCommand.cc b/src/TorrentAutoSaveCommand.cc
index 5d2154c3..b363e3ca 100644
--- a/src/TorrentAutoSaveCommand.cc
+++ b/src/TorrentAutoSaveCommand.cc
@@ -35,15 +35,21 @@
#include "TorrentAutoSaveCommand.h"
#include "Util.h"
-TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), e(e), interval(interval) {}
+TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ int interval):
+ BtContextAwareCommand(cuid, btContext),
+ e(e),
+ interval(interval) {}
TorrentAutoSaveCommand::~TorrentAutoSaveCommand() {}
bool TorrentAutoSaveCommand::execute() {
- if(checkPoint.elapsed(interval) || e->torrentMan->isHalt()) {
+ if(checkPoint.elapsed(interval) || btRuntime->isHalt()) {
checkPoint.reset();
- e->torrentMan->save();
- if(e->torrentMan->isHalt()) {
+ btProgressInfoFile->save();
+ if(btRuntime->isHalt()) {
return true;
}
}
diff --git a/src/TorrentAutoSaveCommand.h b/src/TorrentAutoSaveCommand.h
index 9c360020..d0f511a3 100644
--- a/src/TorrentAutoSaveCommand.h
+++ b/src/TorrentAutoSaveCommand.h
@@ -35,17 +35,22 @@
#ifndef _D_TORRENT_AUTO_SAVE_COMMAND_H_
#define _D_TORRENT_AUTO_SAVE_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
#include "TimeA2.h"
+#include "BtContext.h"
-class TorrentAutoSaveCommand : public Command {
+class TorrentAutoSaveCommand : public BtContextAwareCommand {
private:
TorrentDownloadEngine* e;
int interval;
Time checkPoint;
public:
- TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval);
+ TorrentAutoSaveCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext,
+ int interval);
+
~TorrentAutoSaveCommand();
bool execute();
diff --git a/src/TorrentConsoleDownloadEngine.cc b/src/TorrentConsoleDownloadEngine.cc
index 3f6ab8b1..e697c718 100644
--- a/src/TorrentConsoleDownloadEngine.cc
+++ b/src/TorrentConsoleDownloadEngine.cc
@@ -34,6 +34,9 @@
/* copyright --> */
#include "TorrentConsoleDownloadEngine.h"
#include "Util.h"
+#include <signal.h>
+
+volatile sig_atomic_t haltRequested = 0;
TorrentConsoleDownloadEngine::TorrentConsoleDownloadEngine() {}
@@ -42,8 +45,8 @@ TorrentConsoleDownloadEngine::~TorrentConsoleDownloadEngine() {}
void TorrentConsoleDownloadEngine::sendStatistics() {
printf("\r ");
printf("\r");
- if(torrentMan->downloadComplete()) {
- printf("Download Completed ");
+ if(pieceStorage->downloadFinished()) {
+ printf("Download Completed.");
} else {
printf("%s/%sB %d%% %s D:%.2f",
Util::llitos(downloadLength, true).c_str(),
@@ -55,7 +58,14 @@ void TorrentConsoleDownloadEngine::sendStatistics() {
}
printf(" U:%.2f(%s) %d peers",
uploadSpeed/1024.0,
- Util::llitos(torrentMan->getUploadLength(), true).c_str(),
- torrentMan->connections);
+ Util::llitos(uploadLength, true).c_str(),
+ btRuntime->getConnections());
fflush(stdout);
}
+
+void TorrentConsoleDownloadEngine::afterEachIteration() {
+ if(haltRequested) {
+ btRuntime->setHalt(true);
+ }
+ TorrentDownloadEngine::afterEachIteration();
+}
diff --git a/src/TorrentConsoleDownloadEngine.h b/src/TorrentConsoleDownloadEngine.h
index 2bbd1f0f..dea43c82 100644
--- a/src/TorrentConsoleDownloadEngine.h
+++ b/src/TorrentConsoleDownloadEngine.h
@@ -43,6 +43,8 @@ protected:
public:
TorrentConsoleDownloadEngine();
~TorrentConsoleDownloadEngine();
+
+ virtual void afterEachIteration();
};
#endif // _D_TORRENT_CONSOLE_DOWNLOAD_ENGINE_H_
diff --git a/src/TorrentDownloadEngine.cc b/src/TorrentDownloadEngine.cc
index 974c1995..30a0587c 100644
--- a/src/TorrentDownloadEngine.cc
+++ b/src/TorrentDownloadEngine.cc
@@ -34,22 +34,35 @@
/* copyright --> */
#include "TorrentDownloadEngine.h"
#include "Util.h"
+#include "BtRegistry.h"
-TorrentDownloadEngine::TorrentDownloadEngine():filenameFixed(false),
- torrentMan(NULL) {}
+TorrentDownloadEngine::TorrentDownloadEngine():
+ filenameFixed(false),
+ btContext(0),
+ btRuntime(0),
+ pieceStorage(0),
+ peerStorage(0),
+ btAnnounce(0),
+ btProgressInfoFile(0) {}
TorrentDownloadEngine::~TorrentDownloadEngine() {
- if(torrentMan != NULL) {
- delete torrentMan;
- }
+}
+
+void TorrentDownloadEngine::setBtContext(const BtContextHandle& btContext) {
+ this->btContext = btContext;
+ btRuntime = BT_RUNTIME(btContext);
+ pieceStorage = PIECE_STORAGE(btContext);
+ peerStorage = PEER_STORAGE(btContext);
+ btAnnounce = BT_ANNOUNCE(btContext);
+ btProgressInfoFile = BT_PROGRESS_INFO_FILE(btContext);
}
void TorrentDownloadEngine::onEndOfRun() {
- torrentMan->diskAdaptor->closeFile();
- if(torrentMan->downloadComplete()) {
- torrentMan->remove();
+ pieceStorage->getDiskAdaptor()->closeFile();
+ if(pieceStorage->downloadFinished()) {
+ btProgressInfoFile->removeFile();
} else {
- torrentMan->save();
+ btProgressInfoFile->save();
}
}
@@ -57,16 +70,12 @@ void TorrentDownloadEngine::initStatistics() {
downloadSpeed = 0;
uploadSpeed = 0;
cp.reset();
- lastCalcStat.reset();
startup.reset();
eta = 0;
avgSpeed = 0;
downloadLength = 0;
+ uploadLength = 0;
totalLength = 0;
- if(torrentMan->isSelectiveDownloadingMode()) {
- selectedDownloadLengthDiff = torrentMan->getDownloadLength()-torrentMan->getCompletedLength();
- selectedTotalLength = torrentMan->getSelectedTotalLength();
- }
}
int TorrentDownloadEngine::calculateSpeed(long long int length, int elapsed) {
@@ -75,10 +84,22 @@ int TorrentDownloadEngine::calculateSpeed(long long int length, int elapsed) {
}
void TorrentDownloadEngine::calculateStat() {
- TransferStat stat = torrentMan->calculateStat();
- downloadSpeed = stat.downloadSpeed;
- uploadSpeed = stat.uploadSpeed;
- avgSpeed = calculateSpeed(stat.sessionDownloadLength, startup.difference());
+ TransferStat stat = peerStorage->calculateStat();
+
+ if(pieceStorage->isSelectiveDownloadingMode()) {
+ downloadLength = pieceStorage->getFilteredCompletedLength();
+ totalLength = pieceStorage->getFilteredTotalLength();
+ } else {
+ downloadLength = pieceStorage->getCompletedLength();
+ totalLength = pieceStorage->getTotalLength();
+ }
+ uploadLength = stat.getSessionUploadLength()+
+ btRuntime->getUploadLengthAtStartup();
+
+ downloadSpeed = stat.getDownloadSpeed();
+ uploadSpeed = stat.getUploadSpeed();
+ avgSpeed = calculateSpeed(stat.getSessionDownloadLength(),
+ startup.difference());
if(avgSpeed < 0) {
avgSpeed = 0;
} else if(avgSpeed != 0) {
@@ -87,20 +108,8 @@ void TorrentDownloadEngine::calculateStat() {
}
void TorrentDownloadEngine::calculateStatistics() {
- if(torrentMan->isSelectiveDownloadingMode()) {
- downloadLength = torrentMan->getDownloadLength()-selectedDownloadLengthDiff;
- totalLength = selectedTotalLength;
- } else {
- downloadLength = torrentMan->getDownloadLength();
- totalLength = torrentMan->getTotalLength();
- }
-
- Time now;
- if(now.getTimeInMillis()-lastCalcStat.getTimeInMillis() >= 1000) {
- calculateStat();
- lastCalcStat = now;
- }
if(cp.difference() >= 1) {
+ calculateStat();
sendStatistics();
cp.reset();
}
diff --git a/src/TorrentDownloadEngine.h b/src/TorrentDownloadEngine.h
index b9ac9f67..f87cd32e 100644
--- a/src/TorrentDownloadEngine.h
+++ b/src/TorrentDownloadEngine.h
@@ -36,8 +36,13 @@
#define _D_TORRENT_DOWNLOAD_ENGINE_H_
#include "DownloadEngine.h"
-#include "TorrentMan.h"
#include "TimeA2.h"
+#include "BtContext.h"
+#include "BtRuntime.h"
+#include "PieceStorage.h"
+#include "PeerStorage.h"
+#include "BtAnnounce.h"
+#include "BtProgressInfoFile.h"
class TorrentDownloadEngine : public DownloadEngine {
private:
@@ -59,8 +64,16 @@ protected:
// The estimated remaining time to complete the download.
int eta;
long long int downloadLength;
+ long long int uploadLength;
long long int totalLength;
+ BtContextHandle btContext;
+ BtRuntimeHandle btRuntime;
+ PieceStorageHandle pieceStorage;
+ PeerStorageHandle peerStorage;
+ BtAnnounceHandle btAnnounce;
+ BtProgressInfoFileHandle btProgressInfoFile;
+
int calculateSpeed(long long int sessionLength, int elapsed);
void calculateStat();
@@ -70,9 +83,9 @@ public:
TorrentDownloadEngine();
virtual ~TorrentDownloadEngine();
- TorrentMan* torrentMan;
-
bool isFilenameFixed() const { return filenameFixed; }
+
+ void setBtContext(const BtContextHandle& btContext);
};
#endif // _D_TORRENT_DOWNLOAD_ENGINE_H_
diff --git a/src/TorrentRequestInfo.cc b/src/TorrentRequestInfo.cc
index 3760da2e..d2ba00d1 100644
--- a/src/TorrentRequestInfo.cc
+++ b/src/TorrentRequestInfo.cc
@@ -36,19 +36,24 @@
#include "DownloadEngineFactory.h"
#include "prefs.h"
#include "Util.h"
+#include "BtRegistry.h"
+#include "DefaultBtContext.h"
extern RequestInfo* requestInfo;
extern void setSignalHander(int signal, void (*handler)(int), int flags);
extern bool timeoutSpecified;
+extern volatile sig_atomic_t haltRequested;
void torrentHandler(int signal) {
- ((TorrentDownloadEngine*)requestInfo->getDownloadEngine())->
- torrentMan->setHalt(true);
+ haltRequested = 1;
}
RequestInfo* TorrentRequestInfo::execute() {
+ BtContextHandle btContext(new DefaultBtContext());
+ btContext->load(torrentFile);
+
if(op->get(PREF_SHOW_FILES) == V_TRUE) {
- showFileEntry();
+ showFileEntry(btContext);
return 0;
}
if(!timeoutSpecified) {
@@ -56,45 +61,42 @@ RequestInfo* TorrentRequestInfo::execute() {
}
// set max_tries to 1. AnnounceList handles retries.
op->put(PREF_MAX_TRIES, "1");
- e = DownloadEngineFactory::newTorrentConsoleEngine(op,
- torrentFile,
- targetFiles);
+ SharedHandle<TorrentDownloadEngine>
+ e(DownloadEngineFactory::newTorrentConsoleEngine(btContext,
+ op,
+ targetFiles));
+
setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND);
try {
e->run();
- if(e->torrentMan->downloadComplete()) {
+ if(PIECE_STORAGE(btContext)->downloadFinished()) {
printDownloadCompeleteMessage();
}
- } catch(Exception* e) {
- logger->error("Exception caught", e);
- delete e;
+ } catch(Exception* ex) {
+ logger->error("Exception caught", ex);
fail = true;
+ delete ex;
}
setSignalHander(SIGINT, SIG_DFL, 0);
setSignalHander(SIGTERM, SIG_DFL, 0);
- delete e;
return 0;
}
-// TODO should be const TorrentMan* torrentMan
-void TorrentRequestInfo::showFileEntry()
+void TorrentRequestInfo::showFileEntry(const BtContextHandle& btContext)
{
- TorrentMan torrentMan;
- torrentMan.option = op;
-
- FileEntries fileEntries =
- torrentMan.readFileEntryFromMetaInfoFile(torrentFile);
+ FileEntries fileEntries = btContext->getFileEntries();
cout << _("Files:") << endl;
cout << "idx|path/length" << endl;
cout << "===+===========================================================================" << endl;
int count = 1;
for(FileEntries::const_iterator itr = fileEntries.begin();
itr != fileEntries.end(); count++, itr++) {
- printf("%3d|%s\n |%s Bytes\n", count, itr->path.c_str(),
- Util::llitos(itr->length, true).c_str());
+ printf("%3d|%s\n |%s Bytes\n", count,
+ (*itr)->getPath().c_str(),
+ Util::llitos((*itr)->getLength(), true).c_str());
cout << "---+---------------------------------------------------------------------------" << endl;
}
}
diff --git a/src/TorrentRequestInfo.h b/src/TorrentRequestInfo.h
index 4c6266c4..82013467 100644
--- a/src/TorrentRequestInfo.h
+++ b/src/TorrentRequestInfo.h
@@ -37,19 +37,19 @@
#include "RequestInfo.h"
#include "TorrentDownloadEngine.h"
+#include "BtContext.h"
class TorrentRequestInfo : public RequestInfo {
private:
string torrentFile;
- TorrentDownloadEngine* e;
Strings targetFiles;
- void showFileEntry();
+ void showFileEntry(const BtContextHandle& btContext);
public:
TorrentRequestInfo(const string& torrentFile, Option* op):
RequestInfo(op),
- torrentFile(torrentFile),
- e(0) {}
+ torrentFile(torrentFile) {}
+
virtual ~TorrentRequestInfo() {}
virtual RequestInfo* execute();
@@ -57,8 +57,10 @@ public:
void setTargetFiles(const Strings& targetFiles) {
this->targetFiles = targetFiles;
}
- virtual DownloadEngine* getDownloadEngine() { return e; }
+ virtual DownloadEngine* getDownloadEngine() {
+ return 0;
+ }
};
#endif // _D_TORRENT_REQUEST_INFO_H_
diff --git a/src/TrackerUpdateCommand.cc b/src/TrackerUpdateCommand.cc
index 1fdebc96..eebe71b4 100644
--- a/src/TrackerUpdateCommand.cc
+++ b/src/TrackerUpdateCommand.cc
@@ -40,7 +40,13 @@
#include "SleepCommand.h"
#include "Util.h"
-TrackerUpdateCommand::TrackerUpdateCommand(int cuid, TorrentDownloadEngine* e):Command(cuid), e(e) {
+extern PeerHandle nullPeer;
+
+TrackerUpdateCommand::TrackerUpdateCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext):
+ BtContextAwareCommand(cuid, btContext), e(e)
+{
logger = LogFactory::getInstance();
}
@@ -77,7 +83,7 @@ char* TrackerUpdateCommand::getTrackerResponse(size_t& trackerResponseLength) {
}
bool TrackerUpdateCommand::execute() {
- if(e->segmentMan->errors > 0 && e->torrentMan->isHalt()) {
+ if(e->segmentMan->errors > 0 && btRuntime->isHalt()) {
return true;
}
if(!e->segmentMan->finished()) {
@@ -89,19 +95,25 @@ bool TrackerUpdateCommand::execute() {
try {
trackerResponse = getTrackerResponse(trackerResponseLength);
- e->torrentMan->processAnnounceResponse(trackerResponse,
- trackerResponseLength);
- while(e->torrentMan->needMorePeerConnection()) {
- PeerHandle peer = e->torrentMan->getPeer();
- int newCuid = e->torrentMan->getNewCuid();
+ btAnnounce->processAnnounceResponse(trackerResponse,
+ trackerResponseLength);
+ while(!btRuntime->isHalt() && btRuntime->lessThanMinPeer()) {
+ PeerHandle peer = peerStorage->getUnusedPeer();
+ if(peer == nullPeer) {
+ break;
+ }
+ int newCuid = btRuntime->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command =
- new PeerInitiateConnectionCommand(newCuid, peer, e);
+ new PeerInitiateConnectionCommand(newCuid,
+ peer,
+ e,
+ btContext);
e->commands.push_back(command);
logger->debug("CUID#%d - Adding new command CUID#%d", cuid, newCuid);
}
- e->torrentMan->announceSuccess();
- e->torrentMan->resetAnnounce();
+ btAnnounce->announceSuccess();
+ btAnnounce->resetAnnounce();
e->segmentMan->init();
} catch(Exception* err) {
logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err);
@@ -111,7 +123,7 @@ bool TrackerUpdateCommand::execute() {
if(trackerResponse) {
delete [] trackerResponse;
}
- if(e->torrentMan->isHalt()) {
+ if(btRuntime->isHalt()) {
return true;
} else {
return prepareForRetry();
diff --git a/src/TrackerUpdateCommand.h b/src/TrackerUpdateCommand.h
index a4a0ad10..13dd5796 100644
--- a/src/TrackerUpdateCommand.h
+++ b/src/TrackerUpdateCommand.h
@@ -35,18 +35,21 @@
#ifndef _D_TRACKER_UPDATE_COMMAND_H_
#define _D_TRACKER_UPDATE_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
#include "Logger.h"
-class TrackerUpdateCommand : public Command {
+class TrackerUpdateCommand : public BtContextAwareCommand {
private:
TorrentDownloadEngine* e;
const Logger* logger;
bool prepareForRetry();
char* getTrackerResponse(size_t& trackerResponseLength);
public:
- TrackerUpdateCommand(int cuid, TorrentDownloadEngine* e);
+ TrackerUpdateCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext);
+
virtual ~TrackerUpdateCommand();
bool execute();
diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc
index cea9a914..825def5d 100644
--- a/src/TrackerWatcherCommand.cc
+++ b/src/TrackerWatcherCommand.cc
@@ -39,17 +39,19 @@
#include "prefs.h"
TrackerWatcherCommand::TrackerWatcherCommand(int cuid,
- TorrentDownloadEngine* e):
- Command(cuid), e(e) {
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext):
+ BtContextAwareCommand(cuid, btContext), e(e)
+{
}
TrackerWatcherCommand::~TrackerWatcherCommand() {}
bool TrackerWatcherCommand::execute() {
- if(e->torrentMan->isHalt() &&
- e->segmentMan->errors > 0 && e->torrentMan->isAllAnnounceFailed() ||
- e->torrentMan->noMoreAnnounce()) {
+ if(btRuntime->isHalt() &&
+ e->segmentMan->errors > 0 && btAnnounce->isAllAnnounceFailed() ||
+ btAnnounce->noMoreAnnounce()) {
return true;
}
Command* command = createCommand();
@@ -62,18 +64,18 @@ bool TrackerWatcherCommand::execute() {
Command* TrackerWatcherCommand::createCommand() {
Command* command = 0;
- if(e->torrentMan->isAnnounceReady()) {
- command = createRequestCommand(e->torrentMan->getAnnounceUrl());
- e->torrentMan->announceStart(); // inside it, trackers++.
+ if(btAnnounce->isAnnounceReady()) {
+ command = createRequestCommand(btAnnounce->getAnnounceUrl());
+ btAnnounce->announceStart(); // inside it, trackers++.
} else if(e->segmentMan->errors > 0) {
- e->torrentMan->announceFailure(); // inside it, trackers = 0.
+ btAnnounce->announceFailure(); // inside it, trackers = 0.
e->segmentMan->init();
- if(e->torrentMan->isAllAnnounceFailed()) {
- e->torrentMan->resetAnnounce();
+ if(btAnnounce->isAllAnnounceFailed()) {
+ btAnnounce->resetAnnounce();
// sleep a few seconds.
command =
new SleepCommand(cuid, e,
- createRequestCommand(e->torrentMan->getAnnounceUrl()),
+ createRequestCommand(btAnnounce->getAnnounceUrl()),
e->option->getAsInt(PREF_RETRY_WAIT));
}
}
@@ -84,7 +86,8 @@ Command* TrackerWatcherCommand::createRequestCommand(const string& url) {
RequestHandle req;
req->setUrl(url);
req->isTorrent = true;
- Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), req, e);
+ Command* command =
+ InitiateConnectionCommandFactory::createInitiateConnectionCommand(btRuntime->getNewCuid(), req, e);
logger->info("CUID#%d - Creating new tracker request command #%d", cuid,
command->getCuid());
return command;
diff --git a/src/TrackerWatcherCommand.h b/src/TrackerWatcherCommand.h
index 17708d1f..785fa7c3 100644
--- a/src/TrackerWatcherCommand.h
+++ b/src/TrackerWatcherCommand.h
@@ -35,10 +35,10 @@
#ifndef _D_TRACKER_WATCHER_COMMAND_H_
#define _D_TRACKER_WATCHER_COMMAND_H_
-#include "Command.h"
+#include "BtContextAwareCommand.h"
#include "TorrentDownloadEngine.h"
-class TrackerWatcherCommand : public Command {
+class TrackerWatcherCommand : public BtContextAwareCommand {
private:
TorrentDownloadEngine* e;
@@ -48,7 +48,10 @@ private:
*/
Command* createRequestCommand(const string& url);
public:
- TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e);
+ TrackerWatcherCommand(int cuid,
+ TorrentDownloadEngine* e,
+ const BtContextHandle& btContext);
+
~TrackerWatcherCommand();
Command* createCommand();
diff --git a/src/Util.cc b/src/Util.cc
index ef2aafd7..ffc38a2a 100644
--- a/src/Util.cc
+++ b/src/Util.cc
@@ -117,20 +117,28 @@ int Util::difftvsec(struct timeval tv1, struct timeval tv2) {
return tv1.tv_sec-tv2.tv_sec;
}
-void Util::slice(Strings& result, const string& src, char delim) {
+void Util::slice(Strings& result, const string& src, char delim, bool doTrim) {
string::size_type p = 0;
while(1) {
string::size_type np = src.find(delim, p);
if(np == string::npos) {
- string term = trim(src.substr(p));
- if(term.size() > 0) {
+ string term = src.substr(p);
+ if(doTrim) {
+ term = trim(term);
+ }
+ if(term.size()) {
result.push_back(term);
}
break;
}
string term = src.substr(p, np-p);
+ if(doTrim) {
+ term = trim(term);
+ }
p = np+1;
- result.push_back(trim(term));
+ if(term.size()) {
+ result.push_back(term);
+ }
}
}
diff --git a/src/Util.h b/src/Util.h
index 7379b35f..9c9ad79a 100644
--- a/src/Util.h
+++ b/src/Util.h
@@ -65,7 +65,7 @@ public:
* Take a string src which is a deliminated list and add its elements
* into result. result is not cleared before conversion begins.
*/
- static void slice(Strings& result, const string& src, char delim);
+ static void slice(Strings& result, const string& src, char delim, bool trim = false);
static string trim(const string& src);
diff --git a/src/common.h b/src/common.h
index 2013fdf3..15ebb043 100644
--- a/src/common.h
+++ b/src/common.h
@@ -71,6 +71,8 @@ public:
}
};
+#include "SharedHandle.h"
+
typedef deque<string> Strings;
typedef deque<int> Integers;
diff --git a/src/main.cc b/src/main.cc
index ca4344c3..a14362a1 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -105,7 +105,7 @@ void showVersion() {
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n");
cout << endl;
- printf(_("Contact Info: %s\n"), "Tasuhiro Tsujikawa <tujikawa at users dot sourceforge dot net>");
+ printf(_("Contact Info: %s\n"), "Tatsuhiro Tsujikawa <tujikawa at users dot sourceforge dot net>");
cout << endl;
}