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".
pull/1/head
Tatsuhiro Tsujikawa 2006-11-05 15:04:17 +00:00
parent b8737b0e7c
commit ec642ad294
119 changed files with 5136 additions and 505 deletions

198
ChangeLog
View File

@ -1,3 +1,201 @@
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".
2006-10-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To simplify TrackerWatherCommand, TrackerUpdateCommand and

3
TODO
View File

@ -19,4 +19,5 @@
* Use SharedHandle where it is useful.
* Add support for "announce-list".
* Rewrite Util::countBit
* Add the ability to display filename or URL to be downloaded in metalink mode.
* Add the ability to display filename or URL to be downloaded in metalink mode.
* Add Turkish translation.

View File

@ -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());
}
}

View File

@ -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:

80
src/AnnounceTier.h Normal file
View File

@ -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_

View File

@ -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);
}

View File

@ -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_

111
src/BtAnnounce.h Normal file
View File

@ -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_

84
src/BtContext.h Normal file
View File

@ -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_

View File

@ -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() {}

View File

@ -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_

59
src/BtProgressInfoFile.h Normal file
View File

@ -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_

130
src/BtRegistry.cc Normal file
View File

@ -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;
}

98
src/BtRegistry.h Normal file
View File

@ -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_

94
src/BtRuntime.h Normal file
View File

@ -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_

View File

@ -36,7 +36,6 @@
#define _D_CANCEL_MESSAGE_H_
#include "SimplePeerMessage.h"
#include "TorrentMan.h"
class CancelMessage : public SimplePeerMessage {
private:

View File

@ -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, '=');

View File

@ -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();
}
}

246
src/DefaultBtAnnounce.cc Normal file
View File

@ -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();
}

122
src/DefaultBtAnnounce.h Normal file
View File

@ -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_

237
src/DefaultBtContext.cc Normal file
View File

@ -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;
}

97
src/DefaultBtContext.h Normal file
View File

@ -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_

View File

@ -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;
}
}

View File

@ -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_

174
src/DefaultPeerStorage.cc Normal file
View File

@ -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++;
}
}
}

90
src/DefaultPeerStorage.h Normal file
View File

@ -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_

433
src/DefaultPieceStorage.cc Normal file
View File

@ -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());
}
}

158
src/DefaultPieceStorage.h Normal file
View File

@ -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_

View File

@ -54,4 +54,5 @@ bool DelegatingPeerListProcessor::canHandle(const MetaEntry* peersEntry) const {
return true;
}
}
return false;
}

View File

@ -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() {

View File

@ -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()) {

View File

@ -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_

View File

@ -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);
}
}

View File

@ -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_

View File

@ -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;

View File

@ -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
};

View File

@ -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;
}

View File

@ -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();
};

64
src/FileEntry.cc Normal file
View File

@ -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());
}
}

View File

@ -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_

View File

@ -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 {

View File

@ -36,7 +36,6 @@
#define _D_HANDSHAKE_MESSAGE_H_
#include "SimplePeerMessage.h"
#include "TorrentMan.h"
#define PSTR "BitTorrent protocol"
#define HANDSHAKE_MESSAGE_LENGTH 68

View File

@ -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;

View File

@ -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() {}

View File

@ -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

View File

@ -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@

View File

@ -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();
}

View File

@ -41,6 +41,7 @@
class MultiDiskAdaptor : public DiskAdaptor {
private:
void setDiskWriterFileEntries();
void mkdir() const;
protected:
virtual string getFilePath() const;
public:

View File

@ -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) {

View File

@ -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;

View File

@ -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_

View File

@ -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 {

View File

@ -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();

View File

@ -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());

View File

@ -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();

View File

@ -38,7 +38,6 @@
#include "Option.h"
#include "Socket.h"
#include "Logger.h"
#include "TorrentMan.h"
#include "PeerMessage.h"
#include "common.h"

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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));

View File

@ -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();

View File

@ -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));
}

View File

@ -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 {

View File

@ -40,8 +40,6 @@
#include "Peer.h"
#include "SharedHandle.h"
typedef deque<PeerHandle> Peers;
class PeerListProcessor {
public:
virtual ~PeerListProcessor() {}

View File

@ -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);

View File

@ -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();

View File

@ -38,6 +38,10 @@
PeerMessage::PeerMessage()
:inProgress(false),
invalidate(false),
uploading(false) {
uploading(false),
btContext(0),
peerStorage(0),
pieceStorage(0)
{
logger = LogFactory::getInstance();
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

128
src/PeerStorage.h Normal file
View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}
}

View File

@ -36,7 +36,6 @@
#define _D_PIECE_MESSAGE_H_
#include "PeerMessage.h"
#include "TorrentMan.h"
class PieceMessage : public PeerMessage {
private:

157
src/PieceStorage.h Normal file
View File

@ -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_

View File

@ -36,7 +36,6 @@
#define _D_REJECT_MESSAGE_H_
#include "SimplePeerMessage.h"
#include "TorrentMan.h"
class RejectMessage : public SimplePeerMessage {
private:

View File

@ -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()->

View File

@ -36,7 +36,6 @@
#define _D_REQUEST_MESSAGE_H_
#include "SimplePeerMessage.h"
#include "TorrentMan.h"
class RequestMessage : public SimplePeerMessage {
private:

View File

@ -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);
}
}
}

View File

@ -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() {}

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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();
}

View File

@ -43,6 +43,8 @@ protected:
public:
TorrentConsoleDownloadEngine();
~TorrentConsoleDownloadEngine();
virtual void afterEachIteration();
};
#endif // _D_TORRENT_CONSOLE_DOWNLOAD_ENGINE_H_

View File

@ -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();
}

View File

@ -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_

View File

@ -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;
}
}

View File

@ -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_

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -71,6 +71,8 @@ public:
}
};
#include "SharedHandle.h"
typedef deque<string> Strings;
typedef deque<int> Integers;

View File

@ -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;
}

View File

@ -227,10 +227,10 @@ Strings createUrls(const string& url) {
}
void AnnounceListTest::testMoveToStoppedAllowedTier() {
AnnounceTier t1(createUrls("tracker1"));
AnnounceTier t2(createUrls("tracker2"));
t2.event = AnnounceTier::COMPLETED;
AnnounceTier t3(createUrls("tracker3"));
AnnounceTierHandle t1(new AnnounceTier(createUrls("tracker1")));
AnnounceTierHandle t2(new AnnounceTier(createUrls("tracker2")));
t2->event = AnnounceTier::COMPLETED;
AnnounceTierHandle t3(new AnnounceTier(createUrls("tracker3")));
AnnounceTiers tiers;
tiers.push_back(t1);
@ -250,10 +250,10 @@ void AnnounceListTest::testMoveToStoppedAllowedTier() {
}
void AnnounceListTest::testMoveToCompletedAllowedTier() {
AnnounceTier t1(createUrls("tracker1"));
AnnounceTier t2(createUrls("tracker2"));
t2.event = AnnounceTier::COMPLETED;
AnnounceTier t3(createUrls("tracker3"));
AnnounceTierHandle t1(new AnnounceTier(createUrls("tracker1")));
AnnounceTierHandle t2(new AnnounceTier(createUrls("tracker2")));
t2->event = AnnounceTier::COMPLETED;
AnnounceTierHandle t3(new AnnounceTier(createUrls("tracker3")));
AnnounceTiers tiers;
tiers.push_back(t1);

View File

@ -95,21 +95,21 @@ void BitfieldManTest::testFilter() {
int index;
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(2, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(3, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(4, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(2, index);
CPPUNIT_ASSERT_EQUAL(5, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(6, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(5, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(7, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
@ -118,17 +118,18 @@ void BitfieldManTest::testFilter() {
// test offset=5, length=2
btman.clearAllBit();
btman.clearAllUseBit();
btman.clearFilter();
btman.addFilter(5, 2);
btman.enableFilter();
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
btman.setBit(index);
CPPUNIT_ASSERT_EQUAL(3, index);
CPPUNIT_ASSERT_EQUAL(2, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
btman.setBit(index);
CPPUNIT_ASSERT_EQUAL(2, index);
CPPUNIT_ASSERT_EQUAL(3, index);
index = btman.getMissingUnusedIndex(peerBt, sizeof(peerBt));
btman.setUseBit(index);
CPPUNIT_ASSERT_EQUAL(-1, index);

88
test/BtRegistryTest.cc Normal file
View File

@ -0,0 +1,88 @@
#include "BtRegistry.h"
#include "Exception.h"
#include "MockPeerStorage.h"
#include "MockPieceStorage.h"
#include "MockBtAnnounce.h"
#include "MockBtProgressInfoFile.h"
#include <string>
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
class BtRegistryTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(BtRegistryTest);
CPPUNIT_TEST(testGetPeerStorage);
CPPUNIT_TEST(testGetPieceStorage);
CPPUNIT_TEST(testGetBtRuntime);
CPPUNIT_TEST(testGetBtAnnounce);
CPPUNIT_TEST(testGetBtProgressInfoFile);
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {
}
void testGetPeerStorage();
void testGetPieceStorage();
void testGetBtRuntime();
void testGetBtAnnounce();
void testGetBtProgressInfoFile();
};
CPPUNIT_TEST_SUITE_REGISTRATION( BtRegistryTest );
void BtRegistryTest::testGetPeerStorage() {
CPPUNIT_ASSERT(!BtRegistry::getPeerStorage("test").get());
PeerStorageHandle peerStorage(new MockPeerStorage());
CPPUNIT_ASSERT(BtRegistry::registerPeerStorage("test",
peerStorage));
CPPUNIT_ASSERT_EQUAL(peerStorage.get(),
BtRegistry::getPeerStorage("test").get());
}
void BtRegistryTest::testGetPieceStorage() {
CPPUNIT_ASSERT(!BtRegistry::getPieceStorage("test").get());
PieceStorageHandle pieceStorage(new MockPieceStorage());
CPPUNIT_ASSERT(BtRegistry::registerPieceStorage("test",
pieceStorage));
CPPUNIT_ASSERT_EQUAL(pieceStorage.get(),
BtRegistry::getPieceStorage("test").get());
}
void BtRegistryTest::testGetBtRuntime() {
CPPUNIT_ASSERT(!BtRegistry::getBtRuntime("test").get());
BtRuntimeHandle runtime;
CPPUNIT_ASSERT(BtRegistry::registerBtRuntime("test", runtime));
CPPUNIT_ASSERT_EQUAL(runtime.get(),
BtRegistry::getBtRuntime("test").get());
}
void BtRegistryTest::testGetBtAnnounce() {
CPPUNIT_ASSERT(!BtRegistry::getBtAnnounce("test").get());
BtAnnounceHandle btAnnounce(new MockBtAnnounce());
CPPUNIT_ASSERT(BtRegistry::registerBtAnnounce("test", btAnnounce));
CPPUNIT_ASSERT_EQUAL(btAnnounce.get(),
BtRegistry::getBtAnnounce("test").get());
}
void BtRegistryTest::testGetBtProgressInfoFile() {
CPPUNIT_ASSERT(!BtRegistry::getBtProgressInfoFile("test").get());
BtProgressInfoFileHandle btProgressInfoFile(new MockBtProgressInfoFile());
CPPUNIT_ASSERT(BtRegistry::registerBtProgressInfoFile("test",
btProgressInfoFile));
CPPUNIT_ASSERT_EQUAL(btProgressInfoFile.get(),
BtRegistry::getBtProgressInfoFile("test").get());
}

Some files were not shown because too many files have changed in this diff Show More