summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-06-28 10:37:15 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-06-28 10:37:15 +0000
commit5699b675268658ea958f7c2306e19849dff9bc41 (patch)
treec654c18eef6f4361cccf13854895b88967aa33ea /src
parent90471d68050ebd05439435330e4d0dbb19c6fd1e (diff)
2009-06-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten DownloadContext and removed SingleFileDownloadContext and BtContext and its derived classes. BitTorrent specific attributes are now set by DownloadContext::setAttribute() with key bittorrent::BITTORRENT. * src/AbstractBtMessage.cc * src/AbstractBtMessage.h * src/AbstractCommand.cc * src/AbstractCommand.h * src/AbstractProxyRequestCommand.cc * src/AbstractProxyResponseCommand.cc * src/ActivePeerConnectionCommand.cc * src/ActivePeerConnectionCommand.h * src/AnnounceList.cc * src/BtCheckIntegrityEntry.cc * src/BtConstants.h * src/BtContext.h: Removed * src/BtDependency.cc * src/BtExtendedMessage.cc * src/BtPieceMessage.cc * src/BtPieceMessage.h * src/BtPostDownloadHandler.cc * src/BtRegistry.cc * src/BtRegistry.h * src/BtSetup.cc * src/CheckIntegrityCommand.cc * src/CheckIntegrityEntry.cc * src/ChecksumCheckIntegrityEntry.cc * src/ConsoleStatCalc.cc * src/ContentTypeRequestGroupCriteria.cc * src/DHTGetPeersCommand.cc * src/DHTGetPeersCommand.h * src/DHTPeerLookupTask.cc * src/DHTPeerLookupTask.h * src/DHTTaskFactory.h * src/DHTTaskFactoryImpl.cc * src/DHTTaskFactoryImpl.h * src/DefaultBtAnnounce.cc * src/DefaultBtAnnounce.h * src/DefaultBtContext.cc: Removed * src/DefaultBtContext.h: Removed * src/DefaultBtInteractive.cc * src/DefaultBtInteractive.h * src/DefaultBtMessageDispatcher.cc * src/DefaultBtMessageDispatcher.h * src/DefaultBtMessageFactory.cc * src/DefaultBtMessageFactory.h * src/DefaultBtMessageReceiver.cc * src/DefaultBtMessageReceiver.h * src/DefaultBtProgressInfoFile.cc * src/DefaultBtRequestFactory.cc * src/DefaultBtRequestFactory.h * src/DefaultExtensionMessageFactory.cc * src/DefaultExtensionMessageFactory.h * src/DefaultPeerStorage.cc * src/DefaultPeerStorage.h * src/DefaultPieceStorage.cc * src/DefaultSegmentManFactory.cc * src/DiskAdaptor.cc * src/DiskAdaptor.h * src/DownloadContext.cc * src/DownloadContext.h * src/DownloadEngine.cc * src/DownloadEngineFactory.cc * src/DownloadHandler.cc * src/DownloadResult.h * src/FileAllocationCommand.cc * src/FileAllocationDispatcherCommand.cc * src/FileAllocationEntry.cc * src/FileEntry.h * src/FillRequestGroupCommand.cc * src/FtpDownloadCommand.cc * src/FtpFinishDownloadCommand.cc * src/FtpInitiateConnectionCommand.cc * src/FtpNegotiationCommand.cc * src/FtpTunnelRequestCommand.cc * src/FtpTunnelResponseCommand.cc * src/HandshakeExtensionMessage.cc * src/HandshakeExtensionMessage.h * src/HaveEraseCommand.cc * src/HttpDownloadCommand.cc * src/HttpInitiateConnectionCommand.cc * src/HttpProxyRequestCommand.cc * src/HttpProxyResponseCommand.cc * src/HttpRequest.cc * src/HttpRequest.h * src/HttpRequestCommand.cc * src/HttpResponseCommand.cc * src/HttpServerBodyCommand.cc * src/HttpServerCommand.cc * src/HttpSkipResponseCommand.cc * src/InitiateConnectionCommandFactory.cc * src/InitiatorMSEHandshakeCommand.cc * src/InitiatorMSEHandshakeCommand.h * src/IteratableChecksumValidator.cc * src/IteratableChecksumValidator.h * src/IteratableChunkChecksumValidator.cc * src/MSEHandshake.cc * src/MSEHandshake.h * src/Makefile.am * src/Makefile.in * src/Metalink2RequestGroup.cc * src/MetalinkPostDownloadHandler.cc * src/MultiDiskAdaptor.cc * src/MultiDiskAdaptor.h * src/MultiFileAllocationIterator.cc * src/MultiUrlRequestInfo.cc * src/PeerChokeCommand.cc * src/PeerChokeCommand.h * src/PeerInitiateConnectionCommand.cc * src/PeerInitiateConnectionCommand.h * src/PeerInteractionCommand.cc * src/PeerInteractionCommand.h * src/PeerReceiveHandshakeCommand.cc * src/PieceHashCheckIntegrityEntry.cc * src/RealtimeCommand.cc * src/ReceiverMSEHandshakeCommand.cc * src/RequestGroup.cc * src/RequestGroup.h * src/RequestGroupEntry.cc * src/RequestGroupMan.cc * src/SeedCheckCommand.cc * src/SeedCheckCommand.h * src/SegmentMan.cc * src/ShareRatioSeedCriteria.h * src/SingleFileDownloadContext.cc: Removed * src/SingleFileDownloadContext.h: Removed * src/SleepCommand.cc * src/StreamCheckIntegrityEntry.cc * src/TrackerWatcherCommand.cc * src/TrackerWatcherCommand.h * src/UnknownLengthPieceStorage.cc * src/Util.cc * src/Util.h * src/XmlRpcMethodImpl.cc * src/bittorrent_helper.cc * src/bittorrent_helper.h * src/download_helper.cc * src/main.cc * src/option_processing.cc * test/BitfieldManTest.cc * test/BittorrentHelperTest.cc * test/BtCancelMessageTest.cc * test/BtChokeMessageTest.cc * test/BtDependencyTest.cc * test/BtPieceMessageTest.cc * test/BtPostDownloadHandlerTest.cc * test/BtRegistryTest.cc * test/BtRejectMessageTest.cc * test/BtRequestMessageTest.cc * test/DHTPeerAnnounceStorageTest.cc * test/DefaultBtAnnounceTest.cc * test/DefaultBtContextTest.cc: Removed * test/DefaultBtMessageDispatcherTest.cc * test/DefaultBtMessageFactoryTest.cc * test/DefaultBtProgressInfoFileTest.cc * test/DefaultBtRequestFactoryTest.cc * test/DefaultExtensionMessageFactoryTest.cc * test/DefaultPeerStorageTest.cc * test/DefaultPieceStorageTest.cc * test/DirectDiskAdaptorTest.cc * test/DownloadContextTest.cc * test/DownloadHandlerFactoryTest.cc * test/DownloadHelperTest.cc * test/HandshakeExtensionMessageTest.cc * test/HttpRequestTest.cc * test/HttpResponseTest.cc * test/IteratableChecksumValidatorTest.cc * test/IteratableChunkChecksumValidatorTest.cc * test/MSEHandshakeTest.cc * test/Makefile.am * test/Makefile.in * test/Metalink2RequestGroupTest.cc * test/MetalinkPostDownloadHandlerTest.cc * test/MockBtContext.h: Removed * test/MockDHTTaskFactory.h * test/MockDownloadContext.h: Removed * test/MockPieceStorage.h * test/MultiDiskAdaptorTest.cc * test/MultiFileAllocationIteratorTest.cc * test/RequestGroupManTest.cc * test/RequestGroupTest.cc * test/SegmentManTest.cc * test/ShareRatioSeedCriteriaTest.cc * test/SingleFileDownloadContextTest.cc: Removed * test/UtilTest.cc * test/XmlRpcMethodTest.cc
Diffstat (limited to 'src')
-rw-r--r--src/AbstractBtMessage.cc6
-rw-r--r--src/AbstractBtMessage.h10
-rw-r--r--src/AbstractCommand.cc5
-rw-r--r--src/AbstractCommand.h7
-rw-r--r--src/AbstractProxyRequestCommand.cc1
-rw-r--r--src/AbstractProxyResponseCommand.cc1
-rw-r--r--src/ActivePeerConnectionCommand.cc6
-rw-r--r--src/ActivePeerConnectionCommand.h3
-rw-r--r--src/AnnounceList.cc3
-rw-r--r--src/BtCheckIntegrityEntry.cc1
-rw-r--r--src/BtConstants.h4
-rw-r--r--src/BtContext.h97
-rw-r--r--src/BtDependency.cc49
-rw-r--r--src/BtExtendedMessage.cc1
-rw-r--r--src/BtPieceMessage.cc21
-rw-r--r--src/BtPieceMessage.h4
-rw-r--r--src/BtPostDownloadHandler.cc19
-rw-r--r--src/BtRegistry.cc8
-rw-r--r--src/BtRegistry.h18
-rw-r--r--src/BtSetup.cc28
-rw-r--r--src/CheckIntegrityCommand.cc7
-rw-r--r--src/CheckIntegrityEntry.cc1
-rw-r--r--src/ChecksumCheckIntegrityEntry.cc15
-rw-r--r--src/ConsoleStatCalc.cc17
-rw-r--r--src/ContentTypeRequestGroupCriteria.cc16
-rw-r--r--src/DHTGetPeersCommand.cc13
-rw-r--r--src/DHTGetPeersCommand.h6
-rw-r--r--src/DHTPeerLookupTask.cc18
-rw-r--r--src/DHTPeerLookupTask.h6
-rw-r--r--src/DHTTaskFactory.h4
-rw-r--r--src/DHTTaskFactoryImpl.cc3
-rw-r--r--src/DHTTaskFactoryImpl.h2
-rw-r--r--src/DefaultBtAnnounce.cc18
-rw-r--r--src/DefaultBtAnnounce.h6
-rw-r--r--src/DefaultBtContext.cc577
-rw-r--r--src/DefaultBtContext.h232
-rw-r--r--src/DefaultBtInteractive.cc25
-rw-r--r--src/DefaultBtInteractive.h6
-rw-r--r--src/DefaultBtMessageDispatcher.cc9
-rw-r--r--src/DefaultBtMessageDispatcher.h6
-rw-r--r--src/DefaultBtMessageFactory.cc51
-rw-r--r--src/DefaultBtMessageFactory.h6
-rw-r--r--src/DefaultBtMessageReceiver.cc15
-rw-r--r--src/DefaultBtMessageReceiver.h6
-rw-r--r--src/DefaultBtProgressInfoFile.cc41
-rw-r--r--src/DefaultBtRequestFactory.cc6
-rw-r--r--src/DefaultBtRequestFactory.h4
-rw-r--r--src/DefaultExtensionMessageFactory.cc11
-rw-r--r--src/DefaultExtensionMessageFactory.h8
-rw-r--r--src/DefaultPeerStorage.cc5
-rw-r--r--src/DefaultPeerStorage.h5
-rw-r--r--src/DefaultPieceStorage.cc17
-rw-r--r--src/DefaultSegmentManFactory.cc5
-rw-r--r--src/DiskAdaptor.cc4
-rw-r--r--src/DiskAdaptor.h12
-rw-r--r--src/DownloadContext.cc92
-rw-r--r--src/DownloadContext.h182
-rw-r--r--src/DownloadEngine.cc15
-rw-r--r--src/DownloadEngineFactory.cc1
-rw-r--r--src/DownloadHandler.cc1
-rw-r--r--src/DownloadResult.h6
-rw-r--r--src/FileAllocationCommand.cc4
-rw-r--r--src/FileAllocationDispatcherCommand.cc1
-rw-r--r--src/FileAllocationEntry.cc1
-rw-r--r--src/FileEntry.h8
-rw-r--r--src/FillRequestGroupCommand.cc1
-rw-r--r--src/FtpDownloadCommand.cc1
-rw-r--r--src/FtpFinishDownloadCommand.cc1
-rw-r--r--src/FtpInitiateConnectionCommand.cc1
-rw-r--r--src/FtpNegotiationCommand.cc25
-rw-r--r--src/FtpTunnelRequestCommand.cc1
-rw-r--r--src/FtpTunnelResponseCommand.cc1
-rw-r--r--src/HandshakeExtensionMessage.cc6
-rw-r--r--src/HandshakeExtensionMessage.h5
-rw-r--r--src/HaveEraseCommand.cc1
-rw-r--r--src/HttpDownloadCommand.cc1
-rw-r--r--src/HttpInitiateConnectionCommand.cc1
-rw-r--r--src/HttpProxyRequestCommand.cc1
-rw-r--r--src/HttpProxyResponseCommand.cc1
-rw-r--r--src/HttpRequest.cc15
-rw-r--r--src/HttpRequest.h14
-rw-r--r--src/HttpRequestCommand.cc2
-rw-r--r--src/HttpResponseCommand.cc32
-rw-r--r--src/HttpServerBodyCommand.cc1
-rw-r--r--src/HttpServerCommand.cc1
-rw-r--r--src/HttpSkipResponseCommand.cc1
-rw-r--r--src/InitiateConnectionCommandFactory.cc1
-rw-r--r--src/InitiatorMSEHandshakeCommand.cc22
-rw-r--r--src/InitiatorMSEHandshakeCommand.h17
-rw-r--r--src/IteratableChecksumValidator.cc7
-rw-r--r--src/IteratableChecksumValidator.h6
-rw-r--r--src/IteratableChunkChecksumValidator.cc4
-rw-r--r--src/MSEHandshake.cc24
-rw-r--r--src/MSEHandshake.h4
-rw-r--r--src/Makefile.am6
-rw-r--r--src/Makefile.in46
-rw-r--r--src/Metalink2RequestGroup.cc19
-rw-r--r--src/MetalinkPostDownloadHandler.cc2
-rw-r--r--src/MultiDiskAdaptor.cc27
-rw-r--r--src/MultiDiskAdaptor.h8
-rw-r--r--src/MultiFileAllocationIterator.cc6
-rw-r--r--src/MultiUrlRequestInfo.cc1
-rw-r--r--src/PeerChokeCommand.cc7
-rw-r--r--src/PeerChokeCommand.h6
-rw-r--r--src/PeerInitiateConnectionCommand.cc10
-rw-r--r--src/PeerInitiateConnectionCommand.h4
-rw-r--r--src/PeerInteractionCommand.cc35
-rw-r--r--src/PeerInteractionCommand.h4
-rw-r--r--src/PeerReceiveHandshakeCommand.cc21
-rw-r--r--src/PieceHashCheckIntegrityEntry.cc6
-rw-r--r--src/RealtimeCommand.cc1
-rw-r--r--src/ReceiverMSEHandshakeCommand.cc9
-rw-r--r--src/RequestGroup.cc168
-rw-r--r--src/RequestGroup.h7
-rw-r--r--src/RequestGroupEntry.cc1
-rw-r--r--src/RequestGroupMan.cc8
-rw-r--r--src/SeedCheckCommand.cc4
-rw-r--r--src/SeedCheckCommand.h3
-rw-r--r--src/SegmentMan.cc5
-rw-r--r--src/ShareRatioSeedCriteria.h11
-rw-r--r--src/SingleFileDownloadContext.cc108
-rw-r--r--src/SingleFileDownloadContext.h180
-rw-r--r--src/SleepCommand.cc1
-rw-r--r--src/StreamCheckIntegrityEntry.cc1
-rw-r--r--src/TrackerWatcherCommand.cc42
-rw-r--r--src/TrackerWatcherCommand.h6
-rw-r--r--src/UnknownLengthPieceStorage.cc8
-rw-r--r--src/Util.cc15
-rw-r--r--src/Util.h18
-rw-r--r--src/XmlRpcMethodImpl.cc46
-rw-r--r--src/bittorrent_helper.cc529
-rw-r--r--src/bittorrent_helper.h132
-rw-r--r--src/download_helper.cc38
-rw-r--r--src/main.cc13
-rw-r--r--src/option_processing.cc6
135 files changed, 1582 insertions, 1970 deletions
diff --git a/src/AbstractBtMessage.cc b/src/AbstractBtMessage.cc
index f2aa432b..d68d49b1 100644
--- a/src/AbstractBtMessage.cc
+++ b/src/AbstractBtMessage.cc
@@ -34,7 +34,6 @@
/* copyright --> */
#include "AbstractBtMessage.h"
#include "Peer.h"
-#include "BtContext.h"
#include "PieceStorage.h"
#include "BtMessageValidator.h"
#include "LogFactory.h"
@@ -73,11 +72,6 @@ AbstractBtMessage::setBtMessageValidator(const SharedHandle<BtMessageValidator>&
this->validator = validator;
}
-void AbstractBtMessage::setBtContext(const SharedHandle<BtContext>& btContext)
-{
- this->btContext = btContext;
-}
-
void AbstractBtMessage::setPieceStorage(const SharedHandle<PieceStorage>& pieceStorage)
{
this->pieceStorage = pieceStorage;
diff --git a/src/AbstractBtMessage.h b/src/AbstractBtMessage.h
index 16fa4013..588bc96e 100644
--- a/src/AbstractBtMessage.h
+++ b/src/AbstractBtMessage.h
@@ -41,7 +41,6 @@
namespace aria2 {
-class BtContext;
class PieceStorage;
class Peer;
class BtMessageDispatcher;
@@ -60,8 +59,6 @@ protected:
std::string _name;
- SharedHandle<BtContext> btContext;
-
SharedHandle<PieceStorage> pieceStorage;
SharedHandle<Peer> peer;
@@ -137,13 +134,6 @@ public:
void setBtMessageValidator(const SharedHandle<BtMessageValidator>& validator);
- void setBtContext(const SharedHandle<BtContext>& btContext);
-
- const SharedHandle<BtContext>& getBtContext() const
- {
- return btContext;
- }
-
void setPieceStorage(const SharedHandle<PieceStorage>& pieceStorage);
void setBtMessageDispatcher(const WeakHandle<BtMessageDispatcher>& dispatcher);
diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc
index b1004a48..57f1a80a 100644
--- a/src/AbstractCommand.cc
+++ b/src/AbstractCommand.cc
@@ -36,7 +36,6 @@
#include <algorithm>
-#include "RequestGroup.h"
#include "Request.h"
#include "DownloadEngine.h"
#include "Option.h"
@@ -231,9 +230,9 @@ bool AbstractCommand::execute() {
void AbstractCommand::tryReserved() {
_requestGroup->removeServerHost(cuid);
- if(_requestGroup->getDownloadContext()->getFileMode() == DownloadContext::SINGLE) {
+ if(_requestGroup->getDownloadContext()->getFileEntries().size() == 1) {
const SharedHandle<FileEntry>& entry =
- _requestGroup->getDownloadContext()->getFileEntries().front();
+ _requestGroup->getDownloadContext()->getFirstFileEntry();
// Don't create new command if currently file length is unknown
// and there are no URI left. Because file length is unknown, we
// can assume that there are no in-flight request object.
diff --git a/src/AbstractCommand.h b/src/AbstractCommand.h
index ba7a7aa4..d7ced6d2 100644
--- a/src/AbstractCommand.h
+++ b/src/AbstractCommand.h
@@ -39,12 +39,12 @@
#include "SharedHandle.h"
#include "TimeA2.h"
#include "FileEntry.h"
+#include "RequestGroup.h"
namespace aria2 {
class Request;
class DownloadEngine;
-class RequestGroup;
class Segment;
class Exception;
class SocketCore;
@@ -122,6 +122,11 @@ protected:
const std::string& resolveProxyMethod(const std::string& protocol) const;
const SharedHandle<Option>& getOption() const;
+
+ const SharedHandle<DownloadContext>& getDownloadContext() const
+ {
+ return _requestGroup->getDownloadContext();
+ }
private:
bool checkSocketIsReadable;
bool checkSocketIsWritable;
diff --git a/src/AbstractProxyRequestCommand.cc b/src/AbstractProxyRequestCommand.cc
index 4fc3fadc..698f5bb4 100644
--- a/src/AbstractProxyRequestCommand.cc
+++ b/src/AbstractProxyRequestCommand.cc
@@ -45,6 +45,7 @@
#include "CookieStorage.h"
#include "AuthConfigFactory.h"
#include "AuthConfig.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/AbstractProxyResponseCommand.cc b/src/AbstractProxyResponseCommand.cc
index 00520cc6..f6b1ac13 100644
--- a/src/AbstractProxyResponseCommand.cc
+++ b/src/AbstractProxyResponseCommand.cc
@@ -45,6 +45,7 @@
#include "DlRetryEx.h"
#include "message.h"
#include "HttpHeader.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/ActivePeerConnectionCommand.cc b/src/ActivePeerConnectionCommand.cc
index 7c76ab4a..7f5709d8 100644
--- a/src/ActivePeerConnectionCommand.cc
+++ b/src/ActivePeerConnectionCommand.cc
@@ -36,7 +36,6 @@
#include "PeerInitiateConnectionCommand.h"
#include "message.h"
#include "DownloadEngine.h"
-#include "BtContext.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
#include "BtRuntime.h"
@@ -48,6 +47,7 @@
#include "SocketCore.h"
#include "BtAnnounce.h"
#include "RequestGroup.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -55,12 +55,10 @@ ActivePeerConnectionCommand::ActivePeerConnectionCommand
(int cuid,
RequestGroup* requestGroup,
DownloadEngine* e,
- const BtContextHandle& btContext,
time_t interval)
:
Command(cuid),
_requestGroup(requestGroup),
- _btContext(btContext),
interval(interval),
e(e),
_numNewConnection(5)
@@ -130,7 +128,7 @@ void ActivePeerConnectionCommand::connectToPeer(const PeerHandle& peer)
peer->usedBy(e->newCUID());
PeerInitiateConnectionCommand* command =
new PeerInitiateConnectionCommand(peer->usedBy(), _requestGroup, peer, e,
- _btContext, _btRuntime);
+ _btRuntime);
command->setPeerStorage(_peerStorage);
command->setPieceStorage(_pieceStorage);
e->commands.push_back(command);
diff --git a/src/ActivePeerConnectionCommand.h b/src/ActivePeerConnectionCommand.h
index d8c7c452..3f22b6a6 100644
--- a/src/ActivePeerConnectionCommand.h
+++ b/src/ActivePeerConnectionCommand.h
@@ -44,7 +44,6 @@ namespace aria2 {
class RequestGroup;
class DownloadEngine;
class Peer;
-class BtContext;
class BtRuntime;
class PieceStorage;
class PeerStorage;
@@ -53,7 +52,6 @@ class BtAnnounce;
class ActivePeerConnectionCommand : public Command {
private:
RequestGroup* _requestGroup;
- SharedHandle<BtContext> _btContext;
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<PieceStorage> _pieceStorage;
SharedHandle<PeerStorage> _peerStorage;
@@ -67,7 +65,6 @@ public:
ActivePeerConnectionCommand(int cuid,
RequestGroup* requestGroup,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
time_t interval);
virtual ~ActivePeerConnectionCommand();
diff --git a/src/AnnounceList.cc b/src/AnnounceList.cc
index ffe97305..e63d0082 100644
--- a/src/AnnounceList.cc
+++ b/src/AnnounceList.cc
@@ -39,6 +39,7 @@
#include "A2STR.h"
#include "SimpleRandomizer.h"
#include "bencode.h"
+#include "Util.h"
namespace aria2 {
@@ -72,7 +73,7 @@ void AnnounceList::reconfigure(const BDE& announceList)
elemItr != elemList.listEnd(); ++elemItr) {
const BDE& data = *elemItr;
if(data.isString()) {
- urls.push_back(data.s());
+ urls.push_back(Util::trim(data.s()));
}
}
if(!urls.empty()) {
diff --git a/src/BtCheckIntegrityEntry.cc b/src/BtCheckIntegrityEntry.cc
index 3197e6c2..8aa1277c 100644
--- a/src/BtCheckIntegrityEntry.cc
+++ b/src/BtCheckIntegrityEntry.cc
@@ -40,6 +40,7 @@
#include "DiskAdaptor.h"
#include "prefs.h"
#include "Option.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/BtConstants.h b/src/BtConstants.h
index 3d1b9cf9..28db953a 100644
--- a/src/BtConstants.h
+++ b/src/BtConstants.h
@@ -41,6 +41,10 @@
typedef std::map<std::string, uint8_t> Extensions;
+#define INFO_HASH_LENGTH 20
+
+#define PIECE_HASH_LENGTH 20
+
#define PEER_ID_LENGTH 20
#define INFO_HASH_LENGTH 20
diff --git a/src/BtContext.h b/src/BtContext.h
deleted file mode 100644
index 858b11cd..00000000
--- a/src/BtContext.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* <!-- 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 "DownloadContext.h"
-
-#include <utility>
-#include <deque>
-
-#include "IntSequence.h"
-
-namespace aria2 {
-
-class AnnounceTier;
-class RequestGroup;
-
-class BtContext:public DownloadContext {
-protected:
- bool _private;
-public:
- BtContext():_private(false) {}
-
- virtual ~BtContext() {}
-
- virtual const unsigned char* getInfoHash() const = 0;
-
- virtual size_t getInfoHashLength() const = 0;
-
- virtual const std::string& getInfoHashAsString() const = 0;
-
- virtual const std::deque<SharedHandle<AnnounceTier> >&
- getAnnounceTiers() const = 0;
-
- virtual void load(const std::string& torrentFile,
- const std::string& overrideName = "") = 0;
-
- /**
- * Returns the peer id of localhost, 20 byte length
- */
- virtual const unsigned char* getPeerId() = 0;
-
- bool isPrivate() const
- {
- return _private;
- }
-
- virtual void computeFastSet
- (std::deque<size_t>& fastSet, const std::string& ipaddr, size_t fastSetSize) = 0;
-
- virtual RequestGroup* getOwnerRequestGroup() = 0;
-
- virtual std::deque<std::pair<std::string, uint16_t> >& getNodes() = 0;
-
- virtual const std::string& getName() const = 0;
-
- virtual void setFileFilter(IntSequence seq) = 0;
-};
-
-class BtContext;
-typedef SharedHandle<BtContext> BtContextHandle;
-
-} // namespace aria2
-
-#endif // _D_BT_CONTEXT_H_
diff --git a/src/BtDependency.cc b/src/BtDependency.cc
index 0109f1de..d8f5c0d3 100644
--- a/src/BtDependency.cc
+++ b/src/BtDependency.cc
@@ -37,7 +37,7 @@
#include "Option.h"
#include "LogFactory.h"
#include "Logger.h"
-#include "DefaultBtContext.h"
+#include "DownloadContext.h"
#include "RecoverableException.h"
#include "message.h"
#include "prefs.h"
@@ -45,6 +45,8 @@
#include "PieceStorage.h"
#include "DiskAdaptor.h"
#include "File.h"
+#include "bittorrent_helper.h"
+#include "DlAbortEx.h"
namespace aria2 {
@@ -62,39 +64,38 @@ bool BtDependency::resolve()
RequestGroupHandle dependee = _dependee;
// cut reference here
_dependee.reset();
- DefaultBtContextHandle btContext(new DefaultBtContext());
- btContext->setDir(_dependant->getDownloadContext()->getDir());
+ SharedHandle<DownloadContext> context(new DownloadContext());
+ context->setDir(_dependant->getDownloadContext()->getDir());
try {
- DiskAdaptorHandle diskAdaptor = dependee->getPieceStorage()->getDiskAdaptor();
+ DiskAdaptorHandle diskAdaptor =
+ dependee->getPieceStorage()->getDiskAdaptor();
diskAdaptor->openExistingFile();
std::string content = Util::toString(diskAdaptor);
-
- std::string overrideName;
- if(Util::startsWith(_dependant->getDownloadContext()->getActualBasePath(),
- _dependant->getDownloadContext()->getDir())) {
- overrideName =
- _dependant->getDownloadContext()->getActualBasePath().substr
- (_dependant->getDownloadContext()->getDir().size());
- if(Util::startsWith(overrideName, "/")) {
- overrideName = overrideName.substr(1);
- }
+ bittorrent::loadFromMemory
+ (content, context, File(dependee->getFirstFilePath()).getBasename());
+ if(context->getFileEntries().size() !=
+ _dependant->getDownloadContext()->getFileEntries().size()) {
+ throw DL_ABORT_EX("The number of file in torrent doesn't match to"
+ " the dependant.");
}
- btContext->loadFromMemory(content,
- File(dependee->getFilePath()).getBasename(),
- overrideName);
- if(_dependant->getOption()->defined(PREF_PEER_ID_PREFIX)) {
- btContext->setPeerIdPrefix
- (_dependant->getOption()->get(PREF_PEER_ID_PREFIX));
+ // Copy file path in _dependant's FileEntries to newly created
+ // context's FileEntries to endorse the path structure of
+ // _dependant.
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator s =
+ _dependant->getDownloadContext()->getFileEntries().begin(),
+ d = context->getFileEntries().begin();
+ d != context->getFileEntries().end(); ++s, ++d) {
+ (*d)->setPath((*s)->getPath());
}
} catch(RecoverableException& e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
- _logger->debug("BtDependency for GID#%d failed. Go without Bt.",
- _dependant->getGID());
+ _logger->info("BtDependency for GID#%d failed. Go without Bt.",
+ _dependant->getGID());
return true;
}
_logger->debug("Dependency resolved for GID#%d", _dependant->getGID());
- _dependant->setDownloadContext(btContext);
- btContext->setOwnerRequestGroup(_dependant.get());
+ _dependant->setDownloadContext(context);
+ context->setOwnerRequestGroup(_dependant.get());
return true;
} else if(_dependee->getNumCommand() == 0) {
// _dependee's download failed.
diff --git a/src/BtExtendedMessage.cc b/src/BtExtendedMessage.cc
index afa19a35..39d61028 100644
--- a/src/BtExtendedMessage.cc
+++ b/src/BtExtendedMessage.cc
@@ -41,7 +41,6 @@
#include "ExtensionMessageFactory.h"
#include "PeerMessageUtil.h"
#include "Peer.h"
-#include "BtContext.h"
#include "DlAbortEx.h"
#include "message.h"
#include "Util.h"
diff --git a/src/BtPieceMessage.cc b/src/BtPieceMessage.cc
index 970a35dd..9381d6e4 100644
--- a/src/BtPieceMessage.cc
+++ b/src/BtPieceMessage.cc
@@ -47,13 +47,13 @@
#include "Logger.h"
#include "Peer.h"
#include "Piece.h"
-#include "BtContext.h"
#include "PieceStorage.h"
#include "BtMessageDispatcher.h"
#include "BtMessageFactory.h"
#include "BtRequestFactory.h"
#include "PeerConnection.h"
#include "StringFormat.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -85,7 +85,7 @@ void BtPieceMessage::doReceivedAction() {
peer->snubbing(false);
peer->updateLatency(slot.getLatencyInMillis());
PieceHandle piece = pieceStorage->getPiece(index);
- off_t offset = (off_t)index*btContext->getPieceLength()+begin;
+ off_t offset = (off_t)index*_downloadContext->getPieceLength()+begin;
logger->debug(MSG_PIECE_RECEIVED,
cuid, index, begin, blockLength, offset, slot.getBlockIndex());
pieceStorage->getDiskAdaptor()->writeData(block, blockLength, offset);
@@ -143,7 +143,7 @@ void BtPieceMessage::send() {
getMessageHeader();
peerConnection->sendMessage(msgHeader, getMessageHeaderLength());
off_t pieceDataOffset =
- (off_t)index*btContext->getPieceLength()+begin;
+ (off_t)index*_downloadContext->getPieceLength()+begin;
size_t writtenLength = sendPieceData(pieceDataOffset, blockLength);
logger->debug("msglength = %lu bytes",
static_cast<unsigned long>(getMessageHeaderLength()+
@@ -176,12 +176,13 @@ bool BtPieceMessage::checkPieceHash(const PieceHandle& piece) {
if(piece->isHashCalculated()) {
logger->debug("Hash is available!! index=%lu",
static_cast<unsigned long>(piece->getIndex()));
- return piece->getHashString() == btContext->getPieceHash(piece->getIndex());
+ return
+ piece->getHashString()==_downloadContext->getPieceHash(piece->getIndex());
} else {
- off_t offset = (off_t)piece->getIndex()*btContext->getPieceLength();
+ off_t offset = (off_t)piece->getIndex()*_downloadContext->getPieceLength();
return MessageDigestHelper::staticSHA1Digest(pieceStorage->getDiskAdaptor(), offset, piece->getLength())
- == btContext->getPieceHash(piece->getIndex());
+ == _downloadContext->getPieceHash(piece->getIndex());
}
}
@@ -203,7 +204,7 @@ void BtPieceMessage::erasePieceOnDisk(const PieceHandle& piece) {
size_t BUFSIZE = 4096;
unsigned char buf[BUFSIZE];
memset(buf, 0, BUFSIZE);
- off_t offset = (off_t)piece->getIndex()*btContext->getPieceLength();
+ off_t offset = (off_t)piece->getIndex()*_downloadContext->getPieceLength();
div_t res = div(piece->getLength(), BUFSIZE);
for(int i = 0; i < res.quot; ++i) {
pieceStorage->getDiskAdaptor()->writeData(buf, BUFSIZE, offset);
@@ -255,4 +256,10 @@ void BtPieceMessage::onCancelSendingPieceEvent
}
}
+void BtPieceMessage::setDownloadContext
+(const SharedHandle<DownloadContext>& downloadContext)
+{
+ _downloadContext = downloadContext;
+}
+
} // namespace aria2
diff --git a/src/BtPieceMessage.h b/src/BtPieceMessage.h
index 9b543035..b87cc40b 100644
--- a/src/BtPieceMessage.h
+++ b/src/BtPieceMessage.h
@@ -41,6 +41,7 @@ namespace aria2 {
class Piece;
class BtPieceMessage;
+class DownloadContext;
typedef SharedHandle<BtPieceMessage> BtPieceMessageHandle;
@@ -51,6 +52,7 @@ private:
uint32_t blockLength;
unsigned char* block;
unsigned char* msgHeader;
+ SharedHandle<DownloadContext> _downloadContext;
static size_t MESSAGE_HEADER_LENGTH;
@@ -100,6 +102,8 @@ public:
void setBlockLength(size_t blockLength) { this->blockLength = blockLength; }
+ void setDownloadContext(const SharedHandle<DownloadContext>& downloadContext);
+
static BtPieceMessageHandle create(const unsigned char* data, size_t dataLength);
virtual void doReceivedAction();
diff --git a/src/BtPostDownloadHandler.cc b/src/BtPostDownloadHandler.cc
index 29685e6e..5e733d75 100644
--- a/src/BtPostDownloadHandler.cc
+++ b/src/BtPostDownloadHandler.cc
@@ -33,7 +33,6 @@
*/
/* copyright --> */
#include "BtPostDownloadHandler.h"
-#include "DefaultBtContext.h"
#include "prefs.h"
#include "RequestGroup.h"
#include "Option.h"
@@ -45,6 +44,8 @@
#include "Util.h"
#include "ContentTypeRequestGroupCriteria.h"
#include "Exception.h"
+#include "DownloadContext.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -64,7 +65,7 @@ void BtPostDownloadHandler::getNextRequestGroups
{
const SharedHandle<Option>& op = requestGroup->getOption();
_logger->debug("Generating RequestGroups for Torrent file %s",
- requestGroup->getFilePath().c_str());
+ requestGroup->getFirstFilePath().c_str());
RequestGroupHandle rg(new RequestGroup(op, std::deque<std::string>()));
std::string content;
@@ -76,14 +77,12 @@ void BtPostDownloadHandler::getNextRequestGroups
requestGroup->getPieceStorage()->getDiskAdaptor()->closeFile();
throw;
}
- DefaultBtContextHandle btContext(new DefaultBtContext());
- btContext->setDir(requestGroup->getDownloadContext()->getDir());
- btContext->loadFromMemory(content, File(requestGroup->getFilePath()).getBasename());
- if(op->defined(PREF_PEER_ID_PREFIX)) {
- btContext->setPeerIdPrefix(op->get(PREF_PEER_ID_PREFIX));
- }
- rg->setDownloadContext(btContext);
- btContext->setOwnerRequestGroup(rg.get());
+ SharedHandle<DownloadContext> context(new DownloadContext());
+ context->setDir(requestGroup->getDownloadContext()->getDir());
+ bittorrent::loadFromMemory(content, context,
+ File(requestGroup->getFirstFilePath()).getBasename());
+ rg->setDownloadContext(context);
+ context->setOwnerRequestGroup(rg.get());
groups.push_back(rg);
}
diff --git a/src/BtRegistry.cc b/src/BtRegistry.cc
index 0c90a20c..158da62b 100644
--- a/src/BtRegistry.cc
+++ b/src/BtRegistry.cc
@@ -34,7 +34,7 @@
/* copyright --> */
#include "BtRegistry.h"
#include "DlAbortEx.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
#include "BtAnnounce.h"
@@ -43,10 +43,10 @@
namespace aria2 {
-SharedHandle<BtContext>
-BtRegistry::getBtContext(const std::string& infoHash) const
+SharedHandle<DownloadContext>
+BtRegistry::getDownloadContext(const std::string& infoHash) const
{
- return get(infoHash)._btContext;
+ return get(infoHash)._downloadContext;
}
void BtRegistry::put(const std::string& infoHash, const BtObject& obj)
diff --git a/src/BtRegistry.h b/src/BtRegistry.h
index bc124b3f..3b3858f8 100644
--- a/src/BtRegistry.h
+++ b/src/BtRegistry.h
@@ -49,23 +49,23 @@ class PieceStorage;
class BtAnnounce;
class BtRuntime;
class BtProgressInfoFile;
-class BtContext;
+class DownloadContext;
struct BtObject {
- SharedHandle<BtContext> _btContext;
+ SharedHandle<DownloadContext> _downloadContext;
SharedHandle<PieceStorage> _pieceStorage;
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<BtAnnounce> _btAnnounce;
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<BtProgressInfoFile> _btProgressInfoFile;
- BtObject(const SharedHandle<BtContext>& btContext,
+ BtObject(const SharedHandle<DownloadContext>& downloadContext,
const SharedHandle<PieceStorage>& pieceStorage,
const SharedHandle<PeerStorage>& peerStorage,
const SharedHandle<BtAnnounce>& btAnnounce,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<BtProgressInfoFile>& btProgressInfoFile):
- _btContext(btContext),
+ _downloadContext(downloadContext),
_pieceStorage(pieceStorage),
_peerStorage(peerStorage),
_btAnnounce(btAnnounce),
@@ -76,7 +76,7 @@ struct BtObject {
bool isNull() const
{
- return _btContext.isNull() &&
+ return _downloadContext.isNull() &&
_pieceStorage.isNull() &&
_peerStorage.isNull() &&
_btAnnounce.isNull() &&
@@ -89,19 +89,21 @@ class BtRegistry {
private:
std::map<std::string, BtObject> _pool;
public:
- SharedHandle<BtContext> getBtContext(const std::string& infoHash) const;
+ SharedHandle<DownloadContext>
+ getDownloadContext(const std::string& infoHash) const;
void put(const std::string& infoHash, const BtObject& obj);
BtObject get(const std::string& infoHash) const;
template<typename OutputIterator>
- void getAllBtContext(OutputIterator dest)
+ OutputIterator getAllDownloadContext(OutputIterator dest)
{
for(std::map<std::string, BtObject>::const_iterator i = _pool.begin();
i != _pool.end(); ++i) {
- *dest++ = (*i).second._btContext;
+ *dest++ = (*i).second._downloadContext;
}
+ return dest;
}
void removeAll();
diff --git a/src/BtSetup.cc b/src/BtSetup.cc
index 26472d98..ea339780 100644
--- a/src/BtSetup.cc
+++ b/src/BtSetup.cc
@@ -58,6 +58,7 @@
#include "BtProgressInfoFile.h"
#include "BtAnnounce.h"
#include "BtRuntime.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -68,11 +69,13 @@ void BtSetup::setup(std::deque<Command*>& commands,
DownloadEngine* e,
const Option* option)
{
- BtContextHandle btContext(dynamic_pointer_cast<BtContext>(requestGroup->getDownloadContext()));
- if(btContext.isNull()) {
+ if(!requestGroup->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
return;
}
- BtObject btObject = e->getBtRegistry()->get(btContext->getInfoHashAsString());
+ const BDE& torrentAttrs =
+ requestGroup->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
+ BtObject btObject =
+ e->getBtRegistry()->get(torrentAttrs[bittorrent::INFO_HASH].s());
SharedHandle<PieceStorage> pieceStorage = btObject._pieceStorage;
SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
SharedHandle<BtRuntime> btRuntime = btObject._btRuntime;
@@ -80,7 +83,7 @@ void BtSetup::setup(std::deque<Command*>& commands,
// commands
{
TrackerWatcherCommand* c =
- new TrackerWatcherCommand(e->newCUID(), requestGroup, e, btContext);
+ new TrackerWatcherCommand(e->newCUID(), requestGroup, e);
c->setPeerStorage(peerStorage);
c->setPieceStorage(pieceStorage);
c->setBtRuntime(btRuntime);
@@ -90,7 +93,7 @@ void BtSetup::setup(std::deque<Command*>& commands,
}
{
PeerChokeCommand* c =
- new PeerChokeCommand(e->newCUID(), e, btContext);
+ new PeerChokeCommand(e->newCUID(), e);
c->setPeerStorage(peerStorage);
c->setBtRuntime(btRuntime);
@@ -98,8 +101,7 @@ void BtSetup::setup(std::deque<Command*>& commands,
}
{
ActivePeerConnectionCommand* c =
- new ActivePeerConnectionCommand(e->newCUID(), requestGroup, e, btContext,
- 10);
+ new ActivePeerConnectionCommand(e->newCUID(), requestGroup, e, 10);
c->setBtRuntime(btRuntime);
c->setPieceStorage(pieceStorage);
c->setPeerStorage(peerStorage);
@@ -108,11 +110,11 @@ void BtSetup::setup(std::deque<Command*>& commands,
commands.push_back(c);
}
- if(!btContext->isPrivate() && DHTSetup::initialized()) {
- DHTRegistry::_peerAnnounceStorage->addPeerAnnounce(btContext->getInfoHash(),
- peerStorage);
+ if(torrentAttrs[bittorrent::PRIVATE].i() == 0 && DHTSetup::initialized()) {
+ DHTRegistry::_peerAnnounceStorage->addPeerAnnounce
+ (torrentAttrs[bittorrent::INFO_HASH].uc(), peerStorage);
DHTGetPeersCommand* command =
- new DHTGetPeersCommand(e->newCUID(), requestGroup, e, btContext);
+ new DHTGetPeersCommand(e->newCUID(), requestGroup, e);
command->setTaskQueue(DHTRegistry::_taskQueue);
command->setTaskFactory(DHTRegistry::_taskFactory);
command->setBtRuntime(btRuntime);
@@ -129,7 +131,7 @@ void BtSetup::setup(std::deque<Command*>& commands,
if(ratio > 0.0) {
SharedHandle<ShareRatioSeedCriteria> cri
(new ShareRatioSeedCriteria(option->getAsDouble(PREF_SEED_RATIO),
- btContext));
+ requestGroup->getDownloadContext()));
cri->setPieceStorage(pieceStorage);
cri->setPeerStorage(peerStorage);
@@ -138,7 +140,7 @@ void BtSetup::setup(std::deque<Command*>& commands,
}
if(unionCri->getSeedCriterion().size() > 0) {
SeedCheckCommand* c =
- new SeedCheckCommand(e->newCUID(), requestGroup, e, btContext, unionCri);
+ new SeedCheckCommand(e->newCUID(), requestGroup, e, unionCri);
c->setPieceStorage(pieceStorage);
c->setBtRuntime(btRuntime);
commands.push_back(c);
diff --git a/src/CheckIntegrityCommand.cc b/src/CheckIntegrityCommand.cc
index 4c2858e1..d7b92a2e 100644
--- a/src/CheckIntegrityCommand.cc
+++ b/src/CheckIntegrityCommand.cc
@@ -39,6 +39,7 @@
#include "Logger.h"
#include "message.h"
#include "prefs.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -62,13 +63,13 @@ bool CheckIntegrityCommand::executeInternal()
if(_requestGroup->downloadFinished()) {
logger->notice(MSG_VERIFICATION_SUCCESSFUL,
- _requestGroup->getFilePath().c_str());
+ _requestGroup->getDownloadContext()->getBasePath().c_str());
std::deque<Command*> commands;
_entry->onDownloadFinished(commands, _e);
_e->addCommand(commands);
} else {
logger->error(MSG_VERIFICATION_FAILED,
- _requestGroup->getFilePath().c_str());
+ _requestGroup->getDownloadContext()->getBasePath().c_str());
std::deque<Command*> commands;
_entry->onDownloadIncomplete(commands,_e);
_e->addCommand(commands);
@@ -86,7 +87,7 @@ bool CheckIntegrityCommand::handleException(Exception& e)
_e->_checkIntegrityMan->dropPickedEntry();
logger->error(MSG_FILE_VALIDATION_FAILURE, e, cuid);
logger->error(MSG_DOWNLOAD_NOT_COMPLETE,
- cuid, _requestGroup->getFilePath().c_str());
+ cuid, _requestGroup->getDownloadContext()->getBasePath().c_str());
return true;
}
diff --git a/src/CheckIntegrityEntry.cc b/src/CheckIntegrityEntry.cc
index 85b493b9..2d2eb569 100644
--- a/src/CheckIntegrityEntry.cc
+++ b/src/CheckIntegrityEntry.cc
@@ -41,6 +41,7 @@
#include "FileAllocationEntry.h"
#include "DownloadEngine.h"
#include "Option.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/ChecksumCheckIntegrityEntry.cc b/src/ChecksumCheckIntegrityEntry.cc
index a7e62a1f..7a0897fa 100644
--- a/src/ChecksumCheckIntegrityEntry.cc
+++ b/src/ChecksumCheckIntegrityEntry.cc
@@ -34,7 +34,7 @@
/* copyright --> */
#include "ChecksumCheckIntegrityEntry.h"
#include "RequestGroup.h"
-#include "SingleFileDownloadContext.h"
+#include "DownloadContext.h"
#include "FileEntry.h"
#include "IteratableChecksumValidator.h"
#include "DownloadEngine.h"
@@ -49,18 +49,15 @@ ChecksumCheckIntegrityEntry::~ChecksumCheckIntegrityEntry() {}
bool ChecksumCheckIntegrityEntry::isValidationReady()
{
- SingleFileDownloadContextHandle dctx
- (dynamic_pointer_cast<SingleFileDownloadContext>(_requestGroup->getDownloadContext()));
- return !dctx.isNull() && dctx->getChecksum().size() > 0 &&
- dctx->getChecksumHashAlgo().size() > 0;
+ return !_requestGroup->getDownloadContext()->getChecksum().empty() &&
+ !_requestGroup->getDownloadContext()->getChecksumHashAlgo().empty();
}
void ChecksumCheckIntegrityEntry::initValidator()
{
- SingleFileDownloadContextHandle dctx
- (dynamic_pointer_cast<SingleFileDownloadContext>(_requestGroup->getDownloadContext()));
- _validator.reset(new IteratableChecksumValidator(dctx,
- _requestGroup->getPieceStorage()));
+ _validator.reset(new IteratableChecksumValidator
+ (_requestGroup->getDownloadContext(),
+ _requestGroup->getPieceStorage()));
_validator->init();
}
diff --git a/src/ConsoleStatCalc.cc b/src/ConsoleStatCalc.cc
index c6c94631..8add12b6 100644
--- a/src/ConsoleStatCalc.cc
+++ b/src/ConsoleStatCalc.cc
@@ -57,8 +57,9 @@
#include "CheckIntegrityMan.h"
#include "CheckIntegrityEntry.h"
#include "Util.h"
+#include "DownloadContext.h"
#ifdef ENABLE_BITTORRENT
-# include "BtContext.h"
+# include "bittorrent_helper.h"
# include "Peer.h"
# include "PeerStorage.h"
# include "BtRegistry.h"
@@ -83,10 +84,8 @@ static void printProgress
<< "#" << rg->getGID() << " ";
#ifdef ENABLE_BITTORRENT
- SharedHandle<BtContext> btctx =
- dynamic_pointer_cast<BtContext>(rg->getDownloadContext());
-
- if(!btctx.isNull() && rg->downloadFinished()) {
+ if(rg->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT) &&
+ rg->downloadFinished()) {
o << "SEEDING" << "(" << "ratio:";
if(rg->getCompletedLength() > 0) {
o << std::fixed << std::setprecision(1)
@@ -114,9 +113,11 @@ static void printProgress
<< "CN:"
<< rg->getNumConnection();
#ifdef ENABLE_BITTORRENT
- if(!btctx.isNull()) {
+ if(rg->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
+ const BDE& torrentAttrs =
+ rg->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<PeerStorage> ps =
- e->getBtRegistry()->get(btctx->getInfoHashAsString())._peerStorage;
+ e->getBtRegistry()->get(torrentAttrs[bittorrent::INFO_HASH].s())._peerStorage;
std::deque<SharedHandle<Peer> > peers;
ps->getActivePeers(peers);
o << " " << "SEED:"
@@ -155,7 +156,7 @@ public:
{
const char SEP_CHAR = '-';
printProgress(std::cout, rg, _e);
- const std::deque<SharedHandle<FileEntry> >& fileEntries =
+ const std::vector<SharedHandle<FileEntry> >& fileEntries =
rg->getDownloadContext()->getFileEntries();
std::cout << "\n"
<< "FILE: ";
diff --git a/src/ContentTypeRequestGroupCriteria.cc b/src/ContentTypeRequestGroupCriteria.cc
index cd06ab4b..d479bc88 100644
--- a/src/ContentTypeRequestGroupCriteria.cc
+++ b/src/ContentTypeRequestGroupCriteria.cc
@@ -34,9 +34,9 @@
/* copyright --> */
#include "ContentTypeRequestGroupCriteria.h"
#include "RequestGroup.h"
-#include "SingleFileDownloadContext.h"
#include "Util.h"
#include "FileEntry.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -49,15 +49,15 @@ ContentTypeRequestGroupCriteria::~ContentTypeRequestGroupCriteria() {}
bool ContentTypeRequestGroupCriteria::match(const RequestGroup* requestGroup) const
{
- if(forwardMatch(requestGroup->getFilePath(), _extensions)) {
+ if(requestGroup->getDownloadContext()->getFileEntries().size() != 1) {
+ return false;
+ }
+ if(forwardMatch(requestGroup->getFirstFilePath(), _extensions)) {
return true;
} else {
- SingleFileDownloadContextHandle dctx(dynamic_pointer_cast<SingleFileDownloadContext>(requestGroup->getDownloadContext()));
- if(dctx.isNull()) {
- return false;
- } else {
- return exactMatch(dctx->getContentType(), _contentTypes);
- }
+ return exactMatch
+ (requestGroup->getDownloadContext()->getFirstFileEntry()->getContentType(),
+ _contentTypes);
}
}
diff --git a/src/DHTGetPeersCommand.cc b/src/DHTGetPeersCommand.cc
index 594ff8ff..ee65dd84 100644
--- a/src/DHTGetPeersCommand.cc
+++ b/src/DHTGetPeersCommand.cc
@@ -40,21 +40,20 @@
#include "RequestGroup.h"
#include "DHTNode.h"
#include "DHTNodeLookupEntry.h"
-#include "BtContext.h"
#include "BtRuntime.h"
#include "PeerStorage.h"
#include "Peer.h"
#include "Logger.h"
+#include "bittorrent_helper.h"
+#include "DownloadContext.h"
namespace aria2 {
DHTGetPeersCommand::DHTGetPeersCommand(int32_t cuid,
RequestGroup* requestGroup,
- DownloadEngine* e,
- const BtContextHandle& ctx):
+ DownloadEngine* e):
Command(cuid),
_requestGroup(requestGroup),
- _btContext(ctx),
_e(e),
_numRetry(0),
_lastGetPeerTime(0)
@@ -76,9 +75,9 @@ bool DHTGetPeersCommand::execute()
((_numRetry > 0 && _lastGetPeerTime.elapsed(RETRY_INTERVAL)) ||
_lastGetPeerTime.elapsed(GET_PEER_INTERVAL))) {
logger->debug("Issuing PeerLookup for infoHash=%s",
- _btContext->getInfoHashAsString().c_str());
- _task = _taskFactory->createPeerLookupTask(_btContext, _btRuntime,
- _peerStorage);
+ bittorrent::getInfoHashString(_requestGroup->getDownloadContext()).c_str());
+ _task = _taskFactory->createPeerLookupTask
+ (_requestGroup->getDownloadContext(), _btRuntime, _peerStorage);
_taskQueue->addPeriodicTask2(_task);
} else if(!_task.isNull() && _task->finished()) {
_lastGetPeerTime.reset();
diff --git a/src/DHTGetPeersCommand.h b/src/DHTGetPeersCommand.h
index f29bbc8e..dee0e21a 100644
--- a/src/DHTGetPeersCommand.h
+++ b/src/DHTGetPeersCommand.h
@@ -47,7 +47,6 @@ class DHTTaskFactory;
class DHTTask;
class DownloadEngine;
class RequestGroup;
-class BtContext;
class BtRuntime;
class PeerStorage;
@@ -61,8 +60,6 @@ private:
RequestGroup* _requestGroup;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<PeerStorage> _peerStorage;
@@ -80,8 +77,7 @@ private:
Time _lastGetPeerTime;
public:
DHTGetPeersCommand(int32_t cuid, RequestGroup* requestGroup,
- DownloadEngine* e,
- const SharedHandle<BtContext>& ctx);
+ DownloadEngine* e);
virtual ~DHTGetPeersCommand();
diff --git a/src/DHTPeerLookupTask.cc b/src/DHTPeerLookupTask.cc
index 6869498a..6d4a0a9c 100644
--- a/src/DHTPeerLookupTask.cc
+++ b/src/DHTPeerLookupTask.cc
@@ -43,15 +43,15 @@
#include "DHTMessageCallback.h"
#include "PeerStorage.h"
#include "BtRuntime.h"
-#include "BtContext.h"
#include "Util.h"
#include "DHTBucket.h"
+#include "bittorrent_helper.h"
namespace aria2 {
-DHTPeerLookupTask::DHTPeerLookupTask(const SharedHandle<BtContext>& btContext):
- DHTAbstractNodeLookupTask(btContext->getInfoHash()),
- _ctx(btContext) {}
+DHTPeerLookupTask::DHTPeerLookupTask
+(const SharedHandle<DownloadContext>& downloadContext):
+ DHTAbstractNodeLookupTask(bittorrent::getInfoHash(downloadContext)) {}
void
DHTPeerLookupTask::getNodesFromMessage(std::deque<SharedHandle<DHTNode> >& nodes,
@@ -92,11 +92,11 @@ void DHTPeerLookupTask::onFinish()
if((*i)->_used) {
const SharedHandle<DHTNode>& node = (*i)->_node;
SharedHandle<DHTMessage> m =
- _factory->createAnnouncePeerMessage(node,
- _ctx->getInfoHash(),
- _btRuntime->getListenPort(),
- _tokenStorage[Util::toHex(node->getID(),
- DHT_ID_LENGTH)]);
+ _factory->createAnnouncePeerMessage
+ (node,
+ _targetID, // this is infoHash
+ _btRuntime->getListenPort(),
+ _tokenStorage[Util::toHex(node->getID(), DHT_ID_LENGTH)]);
_dispatcher->addMessageToQueue(m);
}
}
diff --git a/src/DHTPeerLookupTask.h b/src/DHTPeerLookupTask.h
index 261e61c3..d448f74a 100644
--- a/src/DHTPeerLookupTask.h
+++ b/src/DHTPeerLookupTask.h
@@ -40,7 +40,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class Peer;
class PeerStorage;
class BtRuntime;
@@ -51,13 +51,11 @@ private:
std::deque<SharedHandle<Peer> > _peers;
- SharedHandle<BtContext> _ctx;
-
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<BtRuntime> _btRuntime;
public:
- DHTPeerLookupTask(const SharedHandle<BtContext>& btContext);
+ DHTPeerLookupTask(const SharedHandle<DownloadContext>& downloadContext);
virtual void getNodesFromMessage(std::deque<SharedHandle<DHTNode> >& nodes,
const SharedHandle<DHTMessage>& message);
diff --git a/src/DHTTaskFactory.h b/src/DHTTaskFactory.h
index b5c8dcf9..91988e1a 100644
--- a/src/DHTTaskFactory.h
+++ b/src/DHTTaskFactory.h
@@ -40,7 +40,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class BtRuntime;
class PeerStorage;
class DHTTask;
@@ -61,7 +61,7 @@ public:
virtual SharedHandle<DHTTask> createBucketRefreshTask() = 0;
virtual SharedHandle<DHTTask>
- createPeerLookupTask(const SharedHandle<BtContext>& ctx,
+ createPeerLookupTask(const SharedHandle<DownloadContext>& ctx,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PeerStorage>& peerStorage) = 0;
diff --git a/src/DHTTaskFactoryImpl.cc b/src/DHTTaskFactoryImpl.cc
index d4e93725..6d794b88 100644
--- a/src/DHTTaskFactoryImpl.cc
+++ b/src/DHTTaskFactoryImpl.cc
@@ -47,7 +47,6 @@
#include "DHTReplaceNodeTask.h"
#include "Peer.h"
#include "DHTNodeLookupEntry.h"
-#include "BtContext.h"
#include "PeerStorage.h"
#include "BtRuntime.h"
#include "DHTMessageCallback.h"
@@ -85,7 +84,7 @@ DHTTaskFactoryImpl::createBucketRefreshTask()
SharedHandle<DHTTask>
DHTTaskFactoryImpl::createPeerLookupTask
-(const SharedHandle<BtContext>& ctx,
+(const SharedHandle<DownloadContext>& ctx,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PeerStorage>& peerStorage)
{
diff --git a/src/DHTTaskFactoryImpl.h b/src/DHTTaskFactoryImpl.h
index 9d8c1649..e6f2e5b2 100644
--- a/src/DHTTaskFactoryImpl.h
+++ b/src/DHTTaskFactoryImpl.h
@@ -77,7 +77,7 @@ public:
virtual SharedHandle<DHTTask> createBucketRefreshTask();
virtual SharedHandle<DHTTask>
- createPeerLookupTask(const SharedHandle<BtContext>& ctx,
+ createPeerLookupTask(const SharedHandle<DownloadContext>& ctx,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PeerStorage>& peerStorage);
diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc
index 377b0ae3..3cdeb360 100644
--- a/src/DefaultBtAnnounce.cc
+++ b/src/DefaultBtAnnounce.cc
@@ -41,7 +41,7 @@
#include "DlAbortEx.h"
#include "message.h"
#include "SimpleRandomizer.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PieceStorage.h"
#include "BtRuntime.h"
#include "PeerStorage.h"
@@ -51,19 +51,21 @@
#include "A2STR.h"
#include "Request.h"
#include "bencode.h"
+#include "bittorrent_helper.h"
namespace aria2 {
-DefaultBtAnnounce::DefaultBtAnnounce(const BtContextHandle& btContext,
- const Option* option):
- btContext(btContext),
+DefaultBtAnnounce::DefaultBtAnnounce
+(const SharedHandle<DownloadContext>& downloadContext,
+ const Option* option):
+ _downloadContext(downloadContext),
trackers(0),
interval(DEFAULT_ANNOUNCE_INTERVAL),
minInterval(DEFAULT_ANNOUNCE_INTERVAL),
_userDefinedInterval(0),
complete(0),
incomplete(0),
- announceList(btContext->getAnnounceTiers()),
+ announceList(downloadContext->getAttribute(bittorrent::BITTORRENT)[bittorrent::ANNOUNCE_LIST]),
option(option),
logger(LogFactory::getInstance()),
_randomizer(SimpleRandomizer::getInstance())
@@ -145,10 +147,10 @@ std::string DefaultBtAnnounce::getAnnounceUrl() {
std::string url = announceList.getAnnounce();
url += uriHasQuery(url) ? "&" : "?";
url += "info_hash=";
- url += Util::torrentUrlencode(btContext->getInfoHash(),
- btContext->getInfoHashLength());
+ url += Util::torrentUrlencode(bittorrent::getInfoHash(_downloadContext),
+ INFO_HASH_LENGTH);
url += "&peer_id=";
- url += Util::torrentUrlencode(btContext->getPeerId(), 20);
+ url += Util::torrentUrlencode(bittorrent::getStaticPeerId(), PEER_ID_LENGTH);
url += "&uploaded=";
url += Util::uitos(stat.getSessionUploadLength());
url += "&downloaded=";
diff --git a/src/DefaultBtAnnounce.h b/src/DefaultBtAnnounce.h
index a561bbec..812cb3e8 100644
--- a/src/DefaultBtAnnounce.h
+++ b/src/DefaultBtAnnounce.h
@@ -41,7 +41,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class Option;
class Logger;
class BtRuntime;
@@ -51,7 +51,7 @@ class Randomizer;
class DefaultBtAnnounce : public BtAnnounce {
private:
- SharedHandle<BtContext> btContext;
+ SharedHandle<DownloadContext> _downloadContext;
unsigned int trackers;
Time prevAnnounceTime;
time_t interval;
@@ -69,7 +69,7 @@ private:
SharedHandle<PieceStorage> pieceStorage;
SharedHandle<PeerStorage> peerStorage;
public:
- DefaultBtAnnounce(const SharedHandle<BtContext>& btContext,
+ DefaultBtAnnounce(const SharedHandle<DownloadContext>& downloadContext,
const Option* option);
virtual ~DefaultBtAnnounce();
diff --git a/src/DefaultBtContext.cc b/src/DefaultBtContext.cc
deleted file mode 100644
index 29aaea47..00000000
--- a/src/DefaultBtContext.cc
+++ /dev/null
@@ -1,577 +0,0 @@
-/* <!-- 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 <cstring>
-#include <ostream>
-#include <functional>
-#include <algorithm>
-#include <vector>
-
-#include "DlAbortEx.h"
-#include "Util.h"
-#include "MessageDigestHelper.h"
-#include "a2netcompat.h"
-#include "AnnounceTier.h"
-#include "SimpleRandomizer.h"
-#include "LogFactory.h"
-#include "Logger.h"
-#include "FileEntry.h"
-#include "message.h"
-#include "PeerMessageUtil.h"
-#include "StringFormat.h"
-#include "A2STR.h"
-#include "bencode.h"
-#include "a2functional.h"
-
-namespace aria2 {
-
-const std::string DefaultBtContext::C_NAME("name");
-
-const std::string DefaultBtContext::C_NAME_UTF8("name.utf-8");
-
-const std::string DefaultBtContext::C_FILES("files");
-
-const std::string DefaultBtContext::C_LENGTH("length");
-
-const std::string DefaultBtContext::C_PATH("path");
-
-const std::string DefaultBtContext::C_PATH_UTF8("path.utf-8");
-
-const std::string DefaultBtContext::C_INFO("info");
-
-const std::string DefaultBtContext::C_PIECES("pieces");
-
-const std::string DefaultBtContext::C_PIECE_LENGTH("piece length");
-
-const std::string DefaultBtContext::C_PRIVATE("private");
-
-const std::string DefaultBtContext::C_PRIVATE_ON("1");
-
-const std::string DefaultBtContext::C_URL_LIST("url-list");
-
-const std::string DefaultBtContext::C_ANNOUNCE("announce");
-
-const std::string DefaultBtContext::C_ANNOUNCE_LIST("announce-list");
-
-const std::string DefaultBtContext::C_NODES("nodes");
-
-const std::string DefaultBtContext::DEFAULT_PEER_ID_PREFIX("-aria2-");
-
-DefaultBtContext::DefaultBtContext():_peerIdPrefix(DEFAULT_PEER_ID_PREFIX),
- _randomizer(SimpleRandomizer::getInstance()),
- _ownerRequestGroup(0),
- _logger(LogFactory::getInstance()) {}
-
-DefaultBtContext::~DefaultBtContext() {}
-
-std::string DefaultBtContext::generatePeerId() const {
- std::string peerId = _peerIdPrefix;
- peerId += Util::randomAlpha(20-_peerIdPrefix.size(), _randomizer);
- if(peerId.size() > 20) {
- peerId.erase(20);
- }
- return peerId;
-}
-
-const unsigned char* DefaultBtContext::getInfoHash() const {
- return infoHash;
-}
-
-size_t DefaultBtContext::getInfoHashLength() const {
- return INFO_HASH_LENGTH;
-}
-
-const std::string& DefaultBtContext::getInfoHashAsString() const {
- return infoHashString;
-}
-
-void DefaultBtContext::clear() {
- memset(infoHash, 0, INFO_HASH_LENGTH);
- infoHashString = A2STR::NIL;
- pieceHashes.clear();
- _fileEntries.clear();
- totalLength = 0;
- pieceLength = 0;
- fileMode = BtContext::SINGLE;
- numPieces = 0;
- name = A2STR::NIL;
- announceTiers.clear();
- _private = false;
-}
-
-void DefaultBtContext::extractPieceHash(const std::string& hashData,
- size_t hashLength)
-{
- size_t numPieces = hashData.size()/hashLength;
- for(size_t i = 0; i < numPieces; ++i) {
- pieceHashes.push_back(Util::toHex(hashData.data()+i*hashLength,
- hashLength));
- }
-}
-
-void DefaultBtContext::extractFileEntries(const BDE& infoDict,
- const std::string& defaultName,
- const std::string& overrideName,
- const std::deque<std::string>& urlList)
-{
- if(overrideName.empty()) {
- std::string nameKey;
- if(infoDict.containsKey(C_NAME_UTF8)) {
- nameKey = C_NAME_UTF8;
- } else {
- nameKey = C_NAME;
- }
- const BDE& nameData = infoDict[nameKey];
- if(nameData.isString()) {
- name = nameData.s();
- } else {
- name = strconcat(File(defaultName).getBasename(), ".file");
- }
- } else {
- name = overrideName;
- }
- const BDE& filesList = infoDict[C_FILES];
- if(filesList.isList()) {
- uint64_t length = 0;
- off_t offset = 0;
- // multi-file mode
- fileMode = BtContext::MULTI;
- for(BDE::List::const_iterator itr = filesList.listBegin();
- itr != filesList.listEnd(); ++itr) {
- const BDE& fileDict = *itr;
- if(!fileDict.isDict()) {
- continue;
- }
-
- const BDE& fileLengthData = fileDict[C_LENGTH];
- if(!fileLengthData.isInteger()) {
- throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
- C_LENGTH.c_str()).str());
- }
- length += fileLengthData.i();
-
- std::string pathKey;
- if(fileDict.containsKey(C_PATH_UTF8)) {
- pathKey = C_PATH_UTF8;
- } else {
- pathKey = C_PATH;
- }
- const BDE& pathList = fileDict[pathKey];
- if(!pathList.isList() || pathList.empty()) {
- throw DL_ABORT_EX("Path is empty.");
- }
-
- std::vector<std::string> pathelem(pathList.size());
- std::transform(pathList.listBegin(), pathList.listEnd(), pathelem.begin(),
- std::mem_fun_ref(&BDE::s));
- std::string path = name;
- strappend(path, "/", Util::joinPath(pathelem.begin(), pathelem.end()));
- // Split path with '/' again because each pathList element can
- // contain "/" inside.
- std::deque<std::string> elements;
- Util::slice(elements, path, '/');
- path = Util::joinPath(elements.begin(), elements.end());
-
- std::deque<std::string> uris;
- std::transform(urlList.begin(), urlList.end(), std::back_inserter(uris),
- std::bind2nd(std::plus<std::string>(), "/"+path));
- FileEntryHandle fileEntry(new FileEntry(strconcat(_dir, "/", path),
- fileLengthData.i(),
- offset, uris));
- _fileEntries.push_back(fileEntry);
- offset += fileEntry->getLength();
- }
- totalLength = length;
- } else {
- // single-file mode;
- fileMode = BtContext::SINGLE;
- const BDE& lengthData = infoDict[C_LENGTH];
- if(!lengthData.isInteger()) {
- throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
- C_LENGTH.c_str()).str());
- }
- totalLength = lengthData.i();
- // Slice path by '/' just in case nasty ".." is included in name
- std::deque<std::string> pathelems;
- Util::slice(pathelems, name, '/');
-
- // For each uri in urlList, if it ends with '/', then
- // concatenate name to it. Specification just says so.
- std::deque<std::string> uris;
- for(std::deque<std::string>::const_iterator i = urlList.begin();
- i != urlList.end(); ++i) {
- if(Util::endsWith(*i, "/")) {
- uris.push_back((*i)+name);
- } else {
- uris.push_back(*i);
- }
- }
-
- SharedHandle<FileEntry> fileEntry
- (new FileEntry(strconcat(_dir, "/",
- Util::joinPath(pathelems.begin(),
- pathelems.end())),
- totalLength, 0, uris));
- _fileEntries.push_back(fileEntry);
- }
-}
-
-void DefaultBtContext::extractAnnounceURI(const BDE& announceData)
-{
- // Assumed announceData is string
- std::deque<std::string> urls;
- urls.push_back(Util::trim(announceData.s()));
- announceTiers.push_back(AnnounceTierHandle(new AnnounceTier(urls)));
-}
-
-void DefaultBtContext::extractAnnounceList(const BDE& announceList)
-{
- // Assumed announceList is string
- for(BDE::List::const_iterator itr = announceList.listBegin();
- itr != announceList.listEnd(); ++itr) {
- const BDE& elemList = *itr;
- if(!elemList.isList()) {
- continue;
- }
- std::deque<std::string> urls;
- for(BDE::List::const_iterator elemItr = elemList.listBegin();
- elemItr != elemList.listEnd(); ++elemItr) {
- const BDE& url = (*elemItr);
- if(url.isString()) {
- urls.push_back(Util::trim(url.s()));
- }
- }
- if(!urls.empty()) {
- AnnounceTierHandle tier(new AnnounceTier(urls));
- announceTiers.push_back(tier);
- }
- }
-}
-
-void DefaultBtContext::extractAnnounce(const BDE& rootDict)
-{
- const BDE& announceList = rootDict[C_ANNOUNCE_LIST];
- if(announceList.isList()) {
- extractAnnounceList(announceList);
- } else {
- const BDE& announce = rootDict[C_ANNOUNCE];
- if(announce.isString()) {
- extractAnnounceURI(announce);
- }
- }
-}
-
-void DefaultBtContext::extractUrlList(std::deque<std::string>& uris,
- const BDE& bde)
-{
- if(bde.isList()) {
- for(BDE::List::const_iterator itr = bde.listBegin();
- itr != bde.listEnd(); ++itr) {
- if((*itr).isString()) {
- uris.push_back((*itr).s());
- }
- }
- } else if(bde.isString()) {
- uris.push_back(bde.s());
- }
-}
-
-void DefaultBtContext::extractNodes(const BDE& nodesList)
-{
- if(!nodesList.isList()) {
- return;
- }
- for(BDE::List::const_iterator i = nodesList.listBegin();
- i != nodesList.listEnd(); ++i) {
- const BDE& addrPairList = (*i);
- if(!addrPairList.isList() || addrPairList.size() != 2) {
- continue;
- }
- const BDE& hostname = addrPairList[0];
- if(!hostname.isString()) {
- continue;
- }
- if(Util::trim(hostname.s()).empty()) {
- continue;
- }
- const BDE& port = addrPairList[1];
- if(!port.isInteger() || !(0 < port.i() && port.i() < 65536)) {
- continue;
- }
- _nodes.push_back(std::pair<std::string, uint16_t>(hostname.s(), port.i()));
- }
-}
-
-void DefaultBtContext::loadFromMemory(const unsigned char* content,
- size_t length,
- const std::string& defaultName,
- const std::string& overrideName)
-{
- processRootDictionary(bencode::decode(content, length), defaultName,
- overrideName);
-}
-
-void DefaultBtContext::load(const std::string& torrentFile,
- const std::string& overrideName) {
- processRootDictionary(bencode::decodeFromFile(torrentFile), torrentFile,
- overrideName);
-}
-
-void DefaultBtContext::processRootDictionary(const BDE& rootDict,
- const std::string& defaultName,
- const std::string& overrideName)
-{
- clear();
- if(!rootDict.isDict()) {
- throw DL_ABORT_EX("torrent file does not contain a root dictionary.");
- }
- const BDE& infoDict = rootDict[C_INFO];
- if(!infoDict.isDict()) {
- throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
- C_INFO.c_str()).str());
- }
- // retrieve infoHash
- std::string encodedInfoDict = bencode::encode(infoDict);
- MessageDigestHelper::digest(infoHash, INFO_HASH_LENGTH,
- MessageDigestContext::SHA1,
- encodedInfoDict.data(),
- encodedInfoDict.size());
- infoHashString = Util::toHex(infoHash, INFO_HASH_LENGTH);
- // calculate the number of pieces
- const BDE& piecesData = infoDict[C_PIECES];
- if(!piecesData.isString()) {
- throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
- C_PIECES.c_str()).str());
- }
- if(piecesData.s().empty()) {
- throw DL_ABORT_EX("The length of piece hash is 0.");
- }
- numPieces = piecesData.s().size()/PIECE_HASH_LENGTH;
- if(numPieces == 0) {
- throw DL_ABORT_EX("The number of pieces is 0.");
- }
- // retrieve piece length
- const BDE& pieceLengthData = infoDict[C_PIECE_LENGTH];
- if(!pieceLengthData.isInteger()) {
- throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
- C_PIECE_LENGTH.c_str()).str());
- }
- pieceLength = pieceLengthData.i();
- // retrieve piece hashes
- extractPieceHash(piecesData.s(), PIECE_HASH_LENGTH);
- // private flag
- const BDE& privateData = infoDict[C_PRIVATE];
- if(privateData.isInteger()) {
- _private = (privateData.i() == 1);
- }
- // retrieve uri-list.
- // This implemantation obeys HTTP-Seeding specification:
- // see http://www.getright.com/seedtorrent.html
- std::deque<std::string> urlList;
- extractUrlList(urlList, rootDict[C_URL_LIST]);
-
- // retrieve file entries
- extractFileEntries(infoDict, defaultName, overrideName, urlList);
- if((totalLength+pieceLength-1)/pieceLength != numPieces) {
- throw DL_ABORT_EX("Too few/many piece hash.");
- }
- // retrieve announce
- extractAnnounce(rootDict);
- // retrieve nodes
- extractNodes(rootDict[C_NODES]);
-}
-
-const std::string& DefaultBtContext::getPieceHash(size_t index) const {
- if(index < numPieces) {
- return pieceHashes[index];
- } else {
- return A2STR::NIL;
- }
-}
-
-uint64_t DefaultBtContext::getTotalLength() const {
- return totalLength;
-}
-
-bool DefaultBtContext::knowsTotalLength() const
-{
- return true;
-}
-
-BtContext::FILE_MODE DefaultBtContext::getFileMode() const {
- return fileMode;
-}
-
-const std::string& DefaultBtContext::getPieceHashAlgo() const
-{
- return MessageDigestContext::SHA1;
-}
-
-const std::deque<SharedHandle<AnnounceTier> >&
-DefaultBtContext::getAnnounceTiers() const
-{
- return announceTiers;
-}
-
-const std::string& DefaultBtContext::getName() const {
- return name;
-}
-
-size_t DefaultBtContext::getPieceLength() const {
- return pieceLength;
-}
-
-size_t DefaultBtContext::getNumPieces() const {
- return numPieces;
-}
-
-std::string DefaultBtContext::getActualBasePath() const
-{
- if(_fileEntries.size() == 1) {
- return _fileEntries.front()->getPath();
- } else {
- return strconcat(_dir, "/", name);
- }
-}
-
-void DefaultBtContext::computeFastSet
-(std::deque<size_t>& fastSet, const std::string& ipaddr, size_t fastSetSize)
-{
- unsigned char compact[6];
- if(!PeerMessageUtil::createcompact(compact, ipaddr, 0)) {
- return;
- }
- if(numPieces < fastSetSize) {
- fastSetSize = numPieces;
- }
- unsigned char tx[24];
- memcpy(tx, compact, 4);
- if((tx[0] & 0x80) == 0 || (tx[0] & 0x40) == 0) {
- tx[2] = 0x00;
- tx[3] = 0x00;
- } else {
- tx[3] = 0x00;
- }
- memcpy(tx+4, infoHash, 20);
- unsigned char x[20];
- MessageDigestHelper::digest(x, sizeof(x), MessageDigestContext::SHA1, tx, 24);
- while(fastSet.size() < fastSetSize) {
- for(size_t i = 0; i < 5 && fastSet.size() < fastSetSize; ++i) {
- size_t j = i*4;
- uint32_t ny;
- memcpy(&ny, x+j, 4);
- uint32_t y = ntohl(ny);
- size_t index = y%numPieces;
- if(std::find(fastSet.begin(), fastSet.end(), index) == fastSet.end()) {
- fastSet.push_back(index);
- }
- }
- unsigned char temp[20];
- MessageDigestHelper::digest(temp, sizeof(temp), MessageDigestContext::SHA1, x, sizeof(x));
- memcpy(x, temp, sizeof(x));
- }
-}
-
-std::ostream& operator<<(std::ostream& o, const DefaultBtContext& ctx)
-{
- o << "*** BitTorrent File Information ***" << "\n";
- o << "Mode: " << (ctx.getFileMode() == DownloadContext::SINGLE ? "Single File Torrent":"Multi File Torrent") << "\n";
- o << "Announce:" << "\n";
- AnnounceTiers tiers = ctx.getAnnounceTiers();
- for(AnnounceTiers::const_iterator itr = tiers.begin(); itr != tiers.end(); ++itr) {
- const AnnounceTierHandle& tier = *itr;
- for(std::deque<std::string>::const_iterator uriItr = tier->urls.begin(); uriItr != tier->urls.end(); ++uriItr) {
- o << " " << *uriItr;
- }
- o << "\n";
- }
- o << "Info Hash: " << ctx.getInfoHashAsString() << "\n";
- o << "Piece Length: " << Util::abbrevSize(ctx.getPieceLength()) << "B\n";
- o << "The Number of Pieces: " << ctx.getNumPieces() << "\n";
- o << "Total Length: " << Util::abbrevSize(ctx.getTotalLength()) << "B\n";
- if(ctx.getFileMode() == DownloadContext::MULTI) {
- o << "Name: " << ctx.getName() << "\n";
- }
- Util::toStream(o, ctx.getFileEntries());
- return o;
-}
-
-void DefaultBtContext::setRandomizer(const RandomizerHandle& randomizer)
-{
- _randomizer = randomizer;
-}
-
-std::deque<std::pair<std::string, uint16_t> >&
-DefaultBtContext::getNodes()
-{
- return _nodes;
-}
-
-void DefaultBtContext::setInfoHash(const unsigned char* infoHash)
-{
- memcpy(this->infoHash, infoHash, sizeof(this->infoHash));
-}
-
-void DefaultBtContext::setFilePathWithIndex
-(size_t index, const std::string& path)
-{
- if(0 < index && index <= _fileEntries.size()) {
- _fileEntries[index-1]->setPath(path);
- } else {
- throw DL_ABORT_EX(StringFormat("No such file with index=%u",
- static_cast<unsigned int>(index)).str());
- }
-}
-
-void DefaultBtContext::setFileFilter(IntSequence seq)
-{
- std::deque<int32_t> fileIndexes = seq.flush();
- std::sort(fileIndexes.begin(), fileIndexes.end());
- fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()),
- fileIndexes.end());
-
- bool selectAll = fileIndexes.empty() || _fileEntries.size() == 1;
-
- int32_t index = 1;
- for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
- _fileEntries.begin(); i != _fileEntries.end(); ++i, ++index) {
- (*i)->setRequested
- (selectAll ||
- std::binary_search(fileIndexes.begin(), fileIndexes.end(), index));
- }
-}
-
-} // namespace aria2
diff --git a/src/DefaultBtContext.h b/src/DefaultBtContext.h
deleted file mode 100644
index a238c7a8..00000000
--- a/src/DefaultBtContext.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/* <!-- 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 <iosfwd>
-
-#include "IntSequence.h"
-
-namespace aria2 {
-
-class Randomizer;
-class Logger;
-class BDE;
-
-#define INFO_HASH_LENGTH 20
-#define PIECE_HASH_LENGTH 20
-
-class DefaultBtContext : public BtContext {
-private:
- unsigned char infoHash[INFO_HASH_LENGTH];
- std::string infoHashString;
- std::deque<std::string> pieceHashes;
- FILE_MODE fileMode;
- uint64_t totalLength;
- size_t pieceLength;
- std::string name;
- size_t numPieces;
- std::string peerId;
- std::string _peerIdPrefix;
- std::deque<SharedHandle<AnnounceTier> > announceTiers;
- std::deque<std::pair<std::string, uint16_t> > _nodes;
- SharedHandle<Randomizer> _randomizer;
-
- RequestGroup* _ownerRequestGroup;
-
- Logger* _logger;
-
- static const std::string C_NAME;
-
- static const std::string C_NAME_UTF8;
-
- static const std::string C_FILES;
-
- static const std::string C_LENGTH;
-
- static const std::string C_PATH;
-
- static const std::string C_PATH_UTF8;
-
- static const std::string C_INFO;
-
- static const std::string C_PIECES;
-
- static const std::string C_PIECE_LENGTH;
-
- static const std::string C_PRIVATE;
-
- // This is just a string "1". Used as a value of "private" flag.
- static const std::string C_PRIVATE_ON;
-
- static const std::string C_URL_LIST;
-
- static const std::string C_ANNOUNCE;
-
- static const std::string C_ANNOUNCE_LIST;
-
- static const std::string C_NODES;
-
- void clear();
- void extractPieceHash(const std::string& hashData, size_t hashLength);
- void extractFileEntries(const BDE& infoDic,
- const std::string& defaultName,
- const std::string& overrideName,
- const std::deque<std::string>& urlList);
- void extractAnnounceURI(const BDE& announceData);
- void extractAnnounceList(const BDE& announceListData);
- void extractAnnounce(const BDE& rootDict);
-
- void extractUrlList(std::deque<std::string>& uris, const BDE& obj);
-
- void extractNodes(const BDE& nodes);
-
- void processRootDictionary(const BDE& rootDic,
- const std::string& defaultName,
- const std::string& overrideName);
-
- public:
- DefaultBtContext();
- virtual ~DefaultBtContext();
-
- virtual const unsigned char* getInfoHash() const;
-
- virtual size_t getInfoHashLength() const;
-
- virtual const std::string& getInfoHashAsString() const;
-
- virtual const std::string& getPieceHash(size_t index) const;
-
- virtual const std::deque<std::string>& getPieceHashes() const
- {
- return pieceHashes;
- }
-
- virtual uint64_t getTotalLength() const;
-
- virtual bool knowsTotalLength() const;
-
- virtual FILE_MODE getFileMode() const;
-
- virtual const std::string& getPieceHashAlgo() const;
-
- virtual const std::deque<SharedHandle<AnnounceTier> >&
- getAnnounceTiers() const;
-
- // Note: Before calling load* function, call setDir() to specify
- // directory. Setting directory after load* function doesn't change
- // the output file path.
- virtual void load(const std::string& torrentFile,
- const std::string& overrideName = "");
-
- void loadFromMemory(const unsigned char* content, size_t length,
- const std::string& defaultName,
- const std::string& overrideName = "");
-
- void loadFromMemory(const std::string& context,
- const std::string& defaultName,
- const std::string& overrideName = "")
- {
- loadFromMemory(reinterpret_cast<const unsigned char*>(context.c_str()),
- context.size(), defaultName, overrideName);
- }
-
- virtual const std::string& getName() const;
-
- virtual size_t getPieceLength() const;
-
- virtual size_t getNumPieces() const;
-
- virtual std::string getActualBasePath() const;
-
- virtual const unsigned char* getPeerId() {
- if(peerId.empty()) {
- peerId = generatePeerId();
- }
- return reinterpret_cast<const unsigned char*>(peerId.c_str());
- }
-
- virtual void computeFastSet
- (std::deque<size_t>& fastSet, const std::string& ipaddr, size_t fastSetSize);
-
- virtual RequestGroup* getOwnerRequestGroup()
- {
- return _ownerRequestGroup;
- }
-
- virtual std::deque<std::pair<std::string, uint16_t> >& getNodes();
-
- virtual void setFileFilter(IntSequence seq);
-
- std::string generatePeerId() const;
-
- void setPeerIdPrefix(const std::string& peerIdPrefix)
- {
- _peerIdPrefix = peerIdPrefix;
- }
-
- // for unit test
- void setInfoHash(const unsigned char* infoHash);
-
- void setNumPieces(size_t numPieces)
- {
- this->numPieces = numPieces;
- }
-
- void setOwnerRequestGroup(RequestGroup* owner)
- {
- _ownerRequestGroup = owner;
- }
-
- void setRandomizer(const SharedHandle<Randomizer>& randomizer);
-
- // Sets file path for spcified index. index starts from 1. The index
- // is the same used in BtContext::setFileFilter(). Please note that
- // path is not the actual file path. The actual file path is
- // getDir()+"/"+path.
- void setFilePathWithIndex(size_t index, const std::string& path);
-
- friend std::ostream& operator<<(std::ostream& o, const DefaultBtContext& ctx);
-
- static const std::string DEFAULT_PEER_ID_PREFIX;
-};
-
-typedef SharedHandle<DefaultBtContext> DefaultBtContextHandle;
-
-} // namespace aria2
-
-#endif // _D_DEFAULT_BT_CONTEXT_H_
diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc
index 5d712744..a69a9cdf 100644
--- a/src/DefaultBtInteractive.cc
+++ b/src/DefaultBtInteractive.cc
@@ -54,7 +54,7 @@
#include "DHTNode.h"
#include "Peer.h"
#include "Piece.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PieceStorage.h"
#include "PeerStorage.h"
#include "BtRuntime.h"
@@ -68,13 +68,15 @@
#include "StringFormat.h"
#include "RequestGroup.h"
#include "RequestGroupMan.h"
+#include "bittorrent_helper.h"
namespace aria2 {
DefaultBtInteractive::DefaultBtInteractive
-(const SharedHandle<BtContext>& btContext, const SharedHandle<Peer>& peer)
+(const SharedHandle<DownloadContext>& downloadContext,
+ const SharedHandle<Peer>& peer)
:
- _btContext(btContext),
+ _downloadContext(downloadContext),
peer(peer),
logger(LogFactory::getInstance()),
allowedFastSetSize(10),
@@ -88,8 +90,8 @@ DefaultBtInteractive::~DefaultBtInteractive() {}
void DefaultBtInteractive::initiateHandshake() {
SharedHandle<BtMessage> message =
- messageFactory->createHandshakeMessage(_btContext->getInfoHash(),
- _btContext->getPeerId());
+ messageFactory->createHandshakeMessage
+ (bittorrent::getInfoHash(_downloadContext), bittorrent::getStaticPeerId());
dispatcher->addMessageToQueue(message);
dispatcher->sendMessages();
}
@@ -100,7 +102,7 @@ BtMessageHandle DefaultBtInteractive::receiveHandshake(bool quickReply) {
if(message.isNull()) {
return SharedHandle<BtMessage>();
}
- if(memcmp(message->getPeerId(), _btContext->getPeerId(),
+ if(memcmp(message->getPeerId(), bittorrent::getStaticPeerId(),
PEER_ID_LENGTH) == 0) {
throw DL_ABORT_EX
(StringFormat
@@ -187,9 +189,12 @@ void DefaultBtInteractive::addBitfieldMessageToQueue() {
void DefaultBtInteractive::addAllowedFastMessageToQueue() {
if(peer->isFastExtensionEnabled()) {
- std::deque<size_t> fastSet;
- _btContext->computeFastSet(fastSet, peer->ipaddr, allowedFastSetSize);
- for(std::deque<size_t>::const_iterator itr = fastSet.begin();
+ std::vector<size_t> fastSet;
+ bittorrent::computeFastSet(fastSet, peer->ipaddr,
+ _downloadContext->getNumPieces(),
+ bittorrent::getInfoHash(_downloadContext),
+ allowedFastSetSize);
+ for(std::vector<size_t>::const_iterator itr = fastSet.begin();
itr != fastSet.end(); ++itr) {
dispatcher->addMessageToQueue
(messageFactory->createAllowedFastMessage(*itr));
@@ -239,7 +244,7 @@ size_t DefaultBtInteractive::receiveMessages() {
size_t msgcount = 0;
for(int i = 0; i < 50; ++i) {
if(_requestGroupMan->doesOverallDownloadSpeedExceed() ||
- _btContext->getOwnerRequestGroup()->doesDownloadSpeedExceed()) {
+ _downloadContext->getOwnerRequestGroup()->doesDownloadSpeedExceed()) {
break;
}
BtMessageHandle message = btMessageReceiver->receiveMessage();
diff --git a/src/DefaultBtInteractive.h b/src/DefaultBtInteractive.h
index ee522aed..1129dbeb 100644
--- a/src/DefaultBtInteractive.h
+++ b/src/DefaultBtInteractive.h
@@ -43,7 +43,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class BtRuntime;
class PieceStorage;
class PeerStorage;
@@ -97,7 +97,7 @@ class DefaultBtInteractive : public BtInteractive {
private:
int32_t cuid;
- SharedHandle<BtContext> _btContext;
+ SharedHandle<DownloadContext> _downloadContext;
SharedHandle<BtRuntime> _btRuntime;
@@ -151,7 +151,7 @@ private:
void addPortMessageToQueue();
public:
- DefaultBtInteractive(const SharedHandle<BtContext>& btContext,
+ DefaultBtInteractive(const SharedHandle<DownloadContext>& downloadContext,
const SharedHandle<Peer>& peer);
virtual ~DefaultBtInteractive();
diff --git a/src/DefaultBtMessageDispatcher.cc b/src/DefaultBtMessageDispatcher.cc
index 1adc3565..fa201198 100644
--- a/src/DefaultBtMessageDispatcher.cc
+++ b/src/DefaultBtMessageDispatcher.cc
@@ -42,7 +42,7 @@
#include "BtChokingEvent.h"
#include "BtMessageFactory.h"
#include "message.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
#include "BtMessage.h"
@@ -87,7 +87,7 @@ void DefaultBtMessageDispatcher::sendMessages() {
messageQueue.pop_front();
if(msg->isUploading() && !msg->isSendingInProgress()) {
if(_requestGroupMan->doesOverallUploadSpeedExceed() ||
- btContext->getOwnerRequestGroup()->doesUploadSpeedExceed()) {
+ _downloadContext->getOwnerRequestGroup()->doesUploadSpeedExceed()) {
tempQueue.push_back(msg);
continue;
}
@@ -412,9 +412,10 @@ void DefaultBtMessageDispatcher::setPeer(const SharedHandle<Peer>& peer)
this->peer = peer;
}
-void DefaultBtMessageDispatcher::setBtContext(const BtContextHandle& btContext)
+void DefaultBtMessageDispatcher::setDownloadContext
+(const SharedHandle<DownloadContext>& downloadContext)
{
- this->btContext = btContext;
+ _downloadContext = downloadContext;
}
void DefaultBtMessageDispatcher::setPieceStorage
diff --git a/src/DefaultBtMessageDispatcher.h b/src/DefaultBtMessageDispatcher.h
index 2b3cc2a3..0b5caae6 100644
--- a/src/DefaultBtMessageDispatcher.h
+++ b/src/DefaultBtMessageDispatcher.h
@@ -40,7 +40,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class PeerStorage;
class PieceStorage;
class BtMessage;
@@ -55,7 +55,7 @@ private:
int32_t cuid;
std::deque<SharedHandle<BtMessage> > messageQueue;
std::deque<RequestSlot> requestSlots;
- SharedHandle<BtContext> btContext;
+ SharedHandle<DownloadContext> _downloadContext;
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<PieceStorage> _pieceStorage;
WeakHandle<BtMessageFactory> messageFactory;
@@ -116,7 +116,7 @@ public:
void setPeer(const SharedHandle<Peer>& peer);
- void setBtContext(const SharedHandle<BtContext>& btContext);
+ void setDownloadContext(const SharedHandle<DownloadContext>& downloadContext);
void setPieceStorage(const SharedHandle<PieceStorage>& pieceStorage);
diff --git a/src/DefaultBtMessageFactory.cc b/src/DefaultBtMessageFactory.cc
index 0c6306a7..17bc280c 100644
--- a/src/DefaultBtMessageFactory.cc
+++ b/src/DefaultBtMessageFactory.cc
@@ -61,11 +61,12 @@
#include "ExtensionMessage.h"
#include "Peer.h"
#include "Piece.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PieceStorage.h"
#include "PeerStorage.h"
#include "StringFormat.h"
#include "ExtensionMessageFactory.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -112,7 +113,7 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
{
SharedHandle<BtMessageValidator> v
(new IndexBtMessageValidator((BtHaveMessage*)msg.get(),
- btContext->getNumPieces()));
+ _downloadContext->getNumPieces()));
msg->setBtMessageValidator(v);
}
break;
@@ -121,7 +122,7 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
{
SharedHandle<BtMessageValidator> v
(new BtBitfieldMessageValidator((BtBitfieldMessage*)msg.get(),
- btContext->getNumPieces()));
+ _downloadContext->getNumPieces()));
msg->setBtMessageValidator(v);
}
break;
@@ -130,7 +131,7 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
SharedHandle<BtMessageValidator> validator
(new RangeBtMessageValidator
(temp.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(temp->getIndex())));
temp->setBtMessageValidator(validator);
msg = temp;
@@ -141,7 +142,7 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
SharedHandle<BtMessageValidator> validator
(new RangeBtMessageValidator
(temp.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(temp->getIndex())));
temp->setBtMessageValidator(validator);
msg = temp;
@@ -151,9 +152,10 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
BtPieceMessageHandle temp = BtPieceMessage::create(data, dataLength);
BtMessageValidatorHandle validator
(new BtPieceMessageValidator(temp.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(temp->getIndex())));
temp->setBtMessageValidator(validator);
+ temp->setDownloadContext(_downloadContext);
msg = temp;
break;
}
@@ -168,7 +170,7 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
SharedHandle<BtMessageValidator> validator
(new RangeBtMessageValidator
(temp.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(temp->getIndex())));
temp->setBtMessageValidator(validator);
msg = temp;
@@ -177,7 +179,8 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
case BtSuggestPieceMessage::ID: {
BtSuggestPieceMessageHandle temp = BtSuggestPieceMessage::create(data, dataLength);
SharedHandle<BtMessageValidator> validator
- (new IndexBtMessageValidator(temp.get(), btContext->getNumPieces()));
+ (new IndexBtMessageValidator(temp.get(),
+ _downloadContext->getNumPieces()));
temp->setBtMessageValidator(validator);
msg = temp;
break;
@@ -185,7 +188,8 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
case BtAllowedFastMessage::ID: {
BtAllowedFastMessageHandle temp = BtAllowedFastMessage::create(data, dataLength);
SharedHandle<BtMessageValidator> validator
- (new IndexBtMessageValidator(temp.get(), btContext->getNumPieces()));
+ (new IndexBtMessageValidator(temp.get(),
+ _downloadContext->getNumPieces()));
temp->setBtMessageValidator(validator);
msg = temp;
break;
@@ -219,7 +223,6 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, size_t dataL
void DefaultBtMessageFactory::setCommonProperty(const AbstractBtMessageHandle& msg) {
msg->setCuid(cuid);
msg->setPeer(peer);
- msg->setBtContext(btContext);
msg->setPieceStorage(_pieceStorage);
msg->setBtMessageDispatcher(dispatcher);
msg->setBtRequestFactory(requestFactory);
@@ -232,8 +235,8 @@ DefaultBtMessageFactory::createHandshakeMessage(const unsigned char* data, size_
{
SharedHandle<BtHandshakeMessage> msg = BtHandshakeMessage::create(data, dataLength);
BtMessageValidatorHandle validator
- (new BtHandshakeMessageValidator(msg.get(),
- btContext->getInfoHash()));
+ (new BtHandshakeMessageValidator
+ (msg.get(), bittorrent::getInfoHash(_downloadContext)));
msg->setBtMessageValidator(validator);
setCommonProperty(msg);
return msg;
@@ -245,8 +248,8 @@ DefaultBtMessageFactory::createHandshakeMessage(const unsigned char* infoHash,
{
SharedHandle<BtHandshakeMessage> msg(new BtHandshakeMessage(infoHash, peerId));
BtMessageValidatorHandle validator
- (new BtHandshakeMessageValidator(msg.get(),
- btContext->getInfoHash()));
+ (new BtHandshakeMessageValidator
+ (msg.get(), bittorrent::getInfoHash(_downloadContext)));
msg->setBtMessageValidator(validator);
msg->setDHTEnabled(_dhtEnabled);
setCommonProperty(msg);
@@ -264,7 +267,7 @@ DefaultBtMessageFactory::createRequestMessage(const PieceHandle& piece, size_t b
SharedHandle<BtMessageValidator> validator
(new RangeBtMessageValidator
(msg.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(msg->getIndex())));
msg->setBtMessageValidator(validator);
setCommonProperty(msg);
@@ -278,7 +281,7 @@ DefaultBtMessageFactory::createCancelMessage(size_t index, uint32_t begin, size_
SharedHandle<BtMessageValidator> validator
(new RangeBtMessageValidator
(msg.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(index)));
msg->setBtMessageValidator(validator);
setCommonProperty(msg);
@@ -291,9 +294,10 @@ DefaultBtMessageFactory::createPieceMessage(size_t index, uint32_t begin, size_t
BtPieceMessageHandle msg(new BtPieceMessage(index, begin, length));
BtMessageValidatorHandle validator
(new BtPieceMessageValidator(msg.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(index)));
msg->setBtMessageValidator(validator);
+ msg->setDownloadContext(_downloadContext);
setCommonProperty(msg);
return msg;
}
@@ -303,7 +307,7 @@ DefaultBtMessageFactory::createHaveMessage(size_t index)
{
BtHaveMessageHandle msg(new BtHaveMessage(index));
SharedHandle<BtMessageValidator> v
- (new IndexBtMessageValidator(msg.get(), btContext->getNumPieces()));
+ (new IndexBtMessageValidator(msg.get(), _downloadContext->getNumPieces()));
msg->setBtMessageValidator(v);
setCommonProperty(msg);
return msg;
@@ -349,7 +353,7 @@ DefaultBtMessageFactory::createBitfieldMessage()
_pieceStorage->getBitfieldLength()));
SharedHandle<BtMessageValidator> v
(new BtBitfieldMessageValidator(msg.get(),
- btContext->getNumPieces()));
+ _downloadContext->getNumPieces()));
msg->setBtMessageValidator(v);
setCommonProperty(msg);
return msg;
@@ -386,7 +390,7 @@ DefaultBtMessageFactory::createRejectMessage(size_t index, uint32_t begin, size_
SharedHandle<BtMessageValidator> validator
(new RangeBtMessageValidator
(msg.get(),
- btContext->getNumPieces(),
+ _downloadContext->getNumPieces(),
_pieceStorage->getPieceLength(index)));
msg->setBtMessageValidator(validator);
setCommonProperty(msg);
@@ -398,7 +402,7 @@ DefaultBtMessageFactory::createAllowedFastMessage(size_t index)
{
BtAllowedFastMessageHandle msg(new BtAllowedFastMessage(index));
SharedHandle<BtMessageValidator> validator
- (new IndexBtMessageValidator(msg.get(), btContext->getNumPieces()));
+ (new IndexBtMessageValidator(msg.get(), _downloadContext->getNumPieces()));
msg->setBtMessageValidator(validator);
setCommonProperty(msg);
return msg;
@@ -435,9 +439,10 @@ void DefaultBtMessageFactory::setPeer(const SharedHandle<Peer>& peer)
this->peer = peer;
}
-void DefaultBtMessageFactory::setBtContext(const SharedHandle<BtContext>& btContext)
+void DefaultBtMessageFactory::setDownloadContext
+(const SharedHandle<DownloadContext>& downloadContext)
{
- this->btContext = btContext;
+ _downloadContext = downloadContext;
}
void DefaultBtMessageFactory::setPieceStorage
diff --git a/src/DefaultBtMessageFactory.h b/src/DefaultBtMessageFactory.h
index c2ef06fc..7b289946 100644
--- a/src/DefaultBtMessageFactory.h
+++ b/src/DefaultBtMessageFactory.h
@@ -39,7 +39,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class PieceStorage;
class PeerStorage;
class Peer;
@@ -56,7 +56,7 @@ class DHTTaskFactory;
class DefaultBtMessageFactory : public BtMessageFactory {
private:
int32_t cuid;
- SharedHandle<BtContext> btContext;
+ SharedHandle<DownloadContext> _downloadContext;
SharedHandle<PieceStorage> _pieceStorage;
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<Peer> peer;
@@ -134,7 +134,7 @@ public:
void setPeer(const SharedHandle<Peer>& peer);
- void setBtContext(const SharedHandle<BtContext>& btContext);
+ void setDownloadContext(const SharedHandle<DownloadContext>& downloadContext);
void setPieceStorage(const SharedHandle<PieceStorage>& pieceStorage);
diff --git a/src/DefaultBtMessageReceiver.cc b/src/DefaultBtMessageReceiver.cc
index d6afbb70..9e5ee0f4 100644
--- a/src/DefaultBtMessageReceiver.cc
+++ b/src/DefaultBtMessageReceiver.cc
@@ -38,13 +38,14 @@
#include "BtHandshakeMessage.h"
#include "message.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "Peer.h"
#include "PeerConnection.h"
#include "BtMessageDispatcher.h"
#include "BtMessageFactory.h"
#include "Logger.h"
#include "LogFactory.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -71,7 +72,8 @@ DefaultBtMessageReceiver::receiveHandshake(bool quickReply)
if(!handshakeSent && quickReply && dataLength >= 48) {
handshakeSent = true;
// check info_hash
- if(memcmp(btContext->getInfoHash(), &data[28], INFO_HASH_LENGTH) == 0) {
+ if(memcmp(bittorrent::getInfoHash(_downloadContext), &data[28],
+ INFO_HASH_LENGTH) == 0) {
sendHandshake();
}
}
@@ -92,8 +94,8 @@ DefaultBtMessageReceiver::receiveAndSendHandshake()
void DefaultBtMessageReceiver::sendHandshake() {
SharedHandle<BtMessage> msg =
- messageFactory->createHandshakeMessage(btContext->getInfoHash(),
- btContext->getPeerId());
+ messageFactory->createHandshakeMessage
+ (bittorrent::getInfoHash(_downloadContext), bittorrent::getStaticPeerId());
dispatcher->addMessageToQueue(msg);
dispatcher->sendMessages();
}
@@ -114,9 +116,10 @@ BtMessageHandle DefaultBtMessageReceiver::receiveMessage() {
}
}
-void DefaultBtMessageReceiver::setBtContext(const SharedHandle<BtContext>& btContext)
+void DefaultBtMessageReceiver::setDownloadContext
+(const SharedHandle<DownloadContext>& downloadContext)
{
- this->btContext = btContext;
+ _downloadContext = downloadContext;
}
void DefaultBtMessageReceiver::setPeer(const SharedHandle<Peer>& peer)
diff --git a/src/DefaultBtMessageReceiver.h b/src/DefaultBtMessageReceiver.h
index 8344eb10..a5bbbf27 100644
--- a/src/DefaultBtMessageReceiver.h
+++ b/src/DefaultBtMessageReceiver.h
@@ -39,7 +39,7 @@
namespace aria2 {
-class BtContext;
+class DownloadContext;
class Peer;
class PeerConnection;
class BtMessageDispatcher;
@@ -50,7 +50,7 @@ class DefaultBtMessageReceiver : public BtMessageReceiver {
private:
int32_t cuid;
bool handshakeSent;
- SharedHandle<BtContext> btContext;
+ SharedHandle<DownloadContext> _downloadContext;
SharedHandle<Peer> peer;
WeakHandle<PeerConnection> peerConnection;
WeakHandle<BtMessageDispatcher> dispatcher;
@@ -77,7 +77,7 @@ public:
return cuid;
}
- void setBtContext(const SharedHandle<BtContext>& btContext);
+ void setDownloadContext(const SharedHandle<DownloadContext>& downloadContext);
void setPeer(const SharedHandle<Peer>& peer);
diff --git a/src/DefaultBtProgressInfoFile.cc b/src/DefaultBtProgressInfoFile.cc
index ef2d7474..9b573f95 100644
--- a/src/DefaultBtProgressInfoFile.cc
+++ b/src/DefaultBtProgressInfoFile.cc
@@ -38,13 +38,8 @@
#include <cstring>
#include <fstream>
-#include "BtContext.h"
#include "PieceStorage.h"
#include "Piece.h"
-#ifdef ENABLE_BITTORRENT
-#include "PeerStorage.h"
-#include "BtRuntime.h"
-#endif // ENABLE_BITTORRENT
#include "BitfieldMan.h"
#include "Option.h"
#include "TransferStat.h"
@@ -59,6 +54,12 @@
#include "DownloadFailureException.h"
#include "StringFormat.h"
#include "array_fun.h"
+#include "DownloadContext.h"
+#ifdef ENABLE_BITTORRENT
+# include "PeerStorage.h"
+# include "BtRuntime.h"
+# include "bittorrent_helper.h"
+#endif // ENABLE_BITTORRENT
namespace aria2 {
@@ -67,13 +68,13 @@ const std::string DefaultBtProgressInfoFile::V0001("0001");
static std::string createFilename(const SharedHandle<DownloadContext>& dctx)
{
- std::string t = dctx->getActualBasePath();
+ std::string t = dctx->getBasePath();
t += ".aria2";
return t;
}
DefaultBtProgressInfoFile::DefaultBtProgressInfoFile
-(const DownloadContextHandle& dctx,
+(const SharedHandle<DownloadContext>& dctx,
const PieceStorageHandle& pieceStorage,
const Option* option):
_dctx(dctx),
@@ -123,13 +124,12 @@ void DefaultBtProgressInfoFile::save() {
if(torrentDownload) {
// infoHashLength:
// length: 32 bits
- BtContextHandle btContext(dynamic_pointer_cast<BtContext>(_dctx));
- uint32_t infoHashLengthNL = htonl(btContext->getInfoHashLength());
+ const unsigned char* infoHash = bittorrent::getInfoHash(_dctx);
+ uint32_t infoHashLengthNL = htonl(INFO_HASH_LENGTH);
o.write(reinterpret_cast<const char*>(&infoHashLengthNL),
sizeof(infoHashLengthNL));
// infoHash:
- o.write(reinterpret_cast<const char*>(btContext->getInfoHash()),
- btContext->getInfoHashLength());
+ o.write(reinterpret_cast<const char*>(infoHash), INFO_HASH_LENGTH);
} else {
// infoHashLength:
// length: 32 bits
@@ -240,15 +240,16 @@ void DefaultBtProgressInfoFile::load()
array_ptr<unsigned char> savedInfoHash(new unsigned char[infoHashLength]);
in.read(reinterpret_cast<char*>
(static_cast<unsigned char*>(savedInfoHash)), infoHashLength);
- BtContextHandle btContext(dynamic_pointer_cast<BtContext>(_dctx));
- if(infoHashCheckEnabled &&
- Util::toHex(savedInfoHash, infoHashLength) !=
- btContext->getInfoHashAsString()) {
- throw DL_ABORT_EX
- (StringFormat("info hash mismatch. expected: %s, actual: %s",
- btContext->getInfoHashAsString().c_str(),
- Util::toHex(savedInfoHash,
- infoHashLength).c_str()).str());
+ if(infoHashCheckEnabled) {
+ const unsigned char* infoHash = bittorrent::getInfoHash(_dctx);
+ if(infoHashLength != INFO_HASH_LENGTH ||
+ memcmp(savedInfoHash, infoHash, INFO_HASH_LENGTH) != 0) {
+ throw DL_ABORT_EX
+ (StringFormat("info hash mismatch. expected: %s, actual: %s",
+ Util::toHex(infoHash, INFO_HASH_LENGTH).c_str(),
+ Util::toHex(savedInfoHash, infoHashLength).c_str()
+ ).str());
+ }
}
}
diff --git a/src/DefaultBtRequestFactory.cc b/src/DefaultBtRequestFactory.cc
index f14462f1..059c411c 100644
--- a/src/DefaultBtRequestFactory.cc
+++ b/src/DefaultBtRequestFactory.cc
@@ -40,7 +40,6 @@
#include "Logger.h"
#include "Piece.h"
#include "Peer.h"
-#include "BtContext.h"
#include "PieceStorage.h"
#include "BtMessageDispatcher.h"
#include "BtMessageFactory.h"
@@ -235,11 +234,6 @@ void DefaultBtRequestFactory::getTargetPieceIndexes
mem_fun_sh(&Piece::getIndex));
}
-void DefaultBtRequestFactory::setBtContext(const SharedHandle<BtContext>& btContext)
-{
- this->btContext = btContext;
-}
-
void DefaultBtRequestFactory::setPieceStorage
(const SharedHandle<PieceStorage>& pieceStorage)
{
diff --git a/src/DefaultBtRequestFactory.h b/src/DefaultBtRequestFactory.h
index a4000368..bcf8c8cf 100644
--- a/src/DefaultBtRequestFactory.h
+++ b/src/DefaultBtRequestFactory.h
@@ -39,7 +39,6 @@
namespace aria2 {
-class BtContext;
class PieceStorage;
class Peer;
class BtMessageDispatcher;
@@ -50,7 +49,6 @@ class Logger;
class DefaultBtRequestFactory : public BtRequestFactory {
private:
int32_t cuid;
- SharedHandle<BtContext> btContext;
SharedHandle<PieceStorage> _pieceStorage;
SharedHandle<Peer> peer;
WeakHandle<BtMessageDispatcher> dispatcher;
@@ -96,8 +94,6 @@ public:
this->cuid = cuid;
}
- void setBtContext(const SharedHandle<BtContext>& btContext);
-
void setPieceStorage(const SharedHandle<PieceStorage>& pieceStorage);
void setPeer(const SharedHandle<Peer>& peer);
diff --git a/src/DefaultExtensionMessageFactory.cc b/src/DefaultExtensionMessageFactory.cc
index 6210d108..f28680a4 100644
--- a/src/DefaultExtensionMessageFactory.cc
+++ b/src/DefaultExtensionMessageFactory.cc
@@ -33,7 +33,6 @@
*/
/* copyright --> */
#include "DefaultExtensionMessageFactory.h"
-#include "BtContext.h"
#include "Peer.h"
#include "DlAbortEx.h"
#include "HandshakeExtensionMessage.h"
@@ -50,10 +49,8 @@ DefaultExtensionMessageFactory::DefaultExtensionMessageFactory():
_logger(LogFactory::getInstance()) {}
DefaultExtensionMessageFactory::DefaultExtensionMessageFactory
-(const BtContextHandle& btContext,
- const PeerHandle& peer,
+(const PeerHandle& peer,
const SharedHandle<ExtensionMessageRegistry>& registry):
- _btContext(btContext),
_peer(peer),
_registry(registry),
_logger(LogFactory::getInstance()) {}
@@ -67,7 +64,6 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
if(extensionMessageID == 0) {
// handshake
HandshakeExtensionMessageHandle m = HandshakeExtensionMessage::create(data, length);
- m->setBtContext(_btContext);
m->setPeer(_peer);
return m;
} else {
@@ -91,11 +87,6 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
}
}
-void DefaultExtensionMessageFactory::setBtContext(const BtContextHandle& btContext)
-{
- _btContext = btContext;
-}
-
void DefaultExtensionMessageFactory::setPeerStorage
(const SharedHandle<PeerStorage>& peerStorage)
{
diff --git a/src/DefaultExtensionMessageFactory.h b/src/DefaultExtensionMessageFactory.h
index a3ffd309..dfc1c0ec 100644
--- a/src/DefaultExtensionMessageFactory.h
+++ b/src/DefaultExtensionMessageFactory.h
@@ -39,7 +39,6 @@
namespace aria2 {
-class BtContext;
class PeerStorage;
class Peer;
class Logger;
@@ -47,8 +46,6 @@ class ExtensionMessageRegistry;
class DefaultExtensionMessageFactory:public ExtensionMessageFactory {
private:
- SharedHandle<BtContext> _btContext;
-
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<Peer> _peer;
@@ -61,8 +58,7 @@ public:
DefaultExtensionMessageFactory();
DefaultExtensionMessageFactory
- (const SharedHandle<BtContext>& btContext,
- const SharedHandle<Peer>& peer,
+ (const SharedHandle<Peer>& peer,
const SharedHandle<ExtensionMessageRegistry>& registry);
virtual ~DefaultExtensionMessageFactory();
@@ -70,8 +66,6 @@ public:
virtual SharedHandle<ExtensionMessage>
createMessage(const unsigned char* data, size_t length);
- void setBtContext(const SharedHandle<BtContext>& btContext);
-
void setPeerStorage(const SharedHandle<PeerStorage>& peerStorage);
void setPeer(const SharedHandle<Peer>& peer);
diff --git a/src/DefaultPeerStorage.cc b/src/DefaultPeerStorage.cc
index 18e36ceb..78116204 100644
--- a/src/DefaultPeerStorage.cc
+++ b/src/DefaultPeerStorage.cc
@@ -41,7 +41,6 @@
#include "message.h"
#include "a2time.h"
#include "Peer.h"
-#include "BtContext.h"
#include "BtRuntime.h"
#include "BtSeederStateChoke.h"
#include "BtLeecherStateChoke.h"
@@ -51,9 +50,7 @@ namespace aria2 {
static const int MAX_PEER_LIST_SIZE = 1024;
-DefaultPeerStorage::DefaultPeerStorage(const BtContextHandle& btContext,
- const Option* option):
- btContext(btContext),
+DefaultPeerStorage::DefaultPeerStorage(const Option* option):
option(option),
logger(LogFactory::getInstance()),
removedPeerSessionDownloadLength(0),
diff --git a/src/DefaultPeerStorage.h b/src/DefaultPeerStorage.h
index 21f4b7ef..c52f0094 100644
--- a/src/DefaultPeerStorage.h
+++ b/src/DefaultPeerStorage.h
@@ -43,7 +43,6 @@
namespace aria2 {
-class BtContext;
class Option;
class Logger;
class BtRuntime;
@@ -53,7 +52,6 @@ class PieceStorage;
class DefaultPeerStorage : public PeerStorage {
private:
- SharedHandle<BtContext> btContext;
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<PieceStorage> _pieceStorage;
const Option* option;
@@ -73,8 +71,7 @@ private:
bool isPeerAlreadyAdded(const SharedHandle<Peer>& peer);
public:
- DefaultPeerStorage(const SharedHandle<BtContext>& btContext,
- const Option* option);
+ DefaultPeerStorage(const Option* option);
virtual ~DefaultPeerStorage();
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
index 3a707558..02547bf0 100644
--- a/src/DefaultPieceStorage.cc
+++ b/src/DefaultPieceStorage.cc
@@ -63,7 +63,7 @@
namespace aria2 {
DefaultPieceStorage::DefaultPieceStorage
-(const DownloadContextHandle& downloadContext, const Option* option):
+(const SharedHandle<DownloadContext>& downloadContext, const Option* option):
downloadContext(downloadContext),
bitfieldMan(BitfieldManFactory::getFactoryInstance()->
createBitfieldMan(downloadContext->getPieceLength(),
@@ -421,10 +421,10 @@ size_t DefaultPieceStorage::getInFlightPieceCompletedLength() const
// not unittested
void DefaultPieceStorage::setupFileFilter()
{
- const std::deque<SharedHandle<FileEntry> >& fileEntries =
+ const std::vector<SharedHandle<FileEntry> >& fileEntries =
downloadContext->getFileEntries();
bool allSelected = true;
- for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
fileEntries.begin(); i != fileEntries.end(); ++i) {
if(!(*i)->isRequested()) {
allSelected = false;
@@ -434,7 +434,7 @@ void DefaultPieceStorage::setupFileFilter()
if(allSelected) {
return;
}
- for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
fileEntries.begin(); i != fileEntries.end(); ++i) {
if((*i)->isRequested()) {
bitfieldMan->addFilter((*i)->getOffset(), (*i)->getLength());
@@ -465,11 +465,12 @@ bool DefaultPieceStorage::allDownloadFinished()
// not unittested
void DefaultPieceStorage::initStorage()
{
- if(downloadContext->getFileMode() == DownloadContext::SINGLE) {
+ if(downloadContext->getFileEntries().size() == 1) {
logger->debug("Instantiating DirectDiskAdaptor");
DirectDiskAdaptorHandle directDiskAdaptor(new DirectDiskAdaptor());
directDiskAdaptor->setTotalLength(downloadContext->getTotalLength());
- directDiskAdaptor->setFileEntries(downloadContext->getFileEntries());
+ directDiskAdaptor->setFileEntries(downloadContext->getFileEntries().begin(),
+ downloadContext->getFileEntries().end());
DiskWriterHandle writer =
_diskWriterFactory->newDiskWriter(directDiskAdaptor->getFilePath());
@@ -480,10 +481,10 @@ void DefaultPieceStorage::initStorage()
directDiskAdaptor->setDiskWriter(writer);
this->diskAdaptor = directDiskAdaptor;
} else {
- // file mode == DownloadContext::MULTI
logger->debug("Instantiating MultiDiskAdaptor");
MultiDiskAdaptorHandle multiDiskAdaptor(new MultiDiskAdaptor());
- multiDiskAdaptor->setFileEntries(downloadContext->getFileEntries());
+ multiDiskAdaptor->setFileEntries(downloadContext->getFileEntries().begin(),
+ downloadContext->getFileEntries().end());
if(option->getAsBool(PREF_ENABLE_DIRECT_IO)) {
multiDiskAdaptor->allowDirectIO();
}
diff --git a/src/DefaultSegmentManFactory.cc b/src/DefaultSegmentManFactory.cc
index 5ed7edef..8f020f98 100644
--- a/src/DefaultSegmentManFactory.cc
+++ b/src/DefaultSegmentManFactory.cc
@@ -42,8 +42,9 @@
namespace aria2 {
SegmentManHandle
-DefaultSegmentManFactory::createNewInstance(const DownloadContextHandle& dctx,
- const PieceStorageHandle& ps)
+DefaultSegmentManFactory::createNewInstance
+(const SharedHandle<DownloadContext>& dctx,
+ const PieceStorageHandle& ps)
{
SegmentManHandle segmentMan(new SegmentMan(_option, dctx, ps));
return segmentMan;
diff --git a/src/DiskAdaptor.cc b/src/DiskAdaptor.cc
index 38e0b3ea..5e17eb2b 100644
--- a/src/DiskAdaptor.cc
+++ b/src/DiskAdaptor.cc
@@ -47,8 +47,4 @@ DiskAdaptor::DiskAdaptor():
DiskAdaptor::~DiskAdaptor() {}
-void DiskAdaptor::setFileEntries(const FileEntries& fileEntries) {
- this->fileEntries = fileEntries;
-}
-
} // namespace aria2
diff --git a/src/DiskAdaptor.h b/src/DiskAdaptor.h
index 6e59826a..cb794391 100644
--- a/src/DiskAdaptor.h
+++ b/src/DiskAdaptor.h
@@ -38,7 +38,7 @@
#include "BinaryStream.h"
#include <string>
-#include <deque>
+#include <vector>
#include "TimeA2.h"
@@ -50,7 +50,7 @@ class FileAllocationIterator;
class DiskAdaptor:public BinaryStream {
protected:
- std::deque<SharedHandle<FileEntry> > fileEntries;
+ std::vector<SharedHandle<FileEntry> > fileEntries;
#ifdef HAVE_POSIX_FALLOCATE
bool _fallocate;
#endif // HAVE_POSIX_FALLOCATE
@@ -73,9 +73,13 @@ public:
virtual uint64_t size() = 0;
- void setFileEntries(const std::deque<SharedHandle<FileEntry> >& fileEntries);
+ template<typename InputIterator>
+ void setFileEntries(InputIterator first, InputIterator last)
+ {
+ fileEntries.assign(first, last);
+ }
- const std::deque<SharedHandle<FileEntry> >& getFileEntries() const
+ const std::vector<SharedHandle<FileEntry> >& getFileEntries() const
{
return fileEntries;
}
diff --git a/src/DownloadContext.cc b/src/DownloadContext.cc
index a5dda4d2..f002eb3d 100644
--- a/src/DownloadContext.cc
+++ b/src/DownloadContext.cc
@@ -37,29 +37,30 @@
#include <algorithm>
#include "FileEntry.h"
+#include "StringFormat.h"
namespace aria2 {
DownloadContext::DownloadContext():
_dir("."),
+ _pieceLength(0),
+ _knowsTotalLength(true),
+ _ownerRequestGroup(0),
_downloadStartTime(0),
_downloadStopTime(_downloadStartTime) {}
-DownloadContext::~DownloadContext() {}
-
-void DownloadContext::setDir(const std::string& dir)
-{
- _dir = dir;
-}
-
-SharedHandle<Signature> DownloadContext::getSignature() const
-{
- return _signature;
-}
-
-void DownloadContext::setSignature(const SharedHandle<Signature>& signature)
+DownloadContext::DownloadContext(size_t pieceLength,
+ uint64_t totalLength,
+ const std::string& path):
+ _dir("."),
+ _pieceLength(pieceLength),
+ _knowsTotalLength(true),
+ _ownerRequestGroup(0),
+ _downloadStartTime(0),
+ _downloadStopTime(_downloadStartTime)
{
- _signature = signature;
+ SharedHandle<FileEntry> fileEntry(new FileEntry(path, totalLength, 0));
+ _fileEntries.push_back(fileEntry);
}
void DownloadContext::resetDownloadStartTime()
@@ -94,7 +95,7 @@ DownloadContext::findFileEntryByOffset(off_t offset) const
SharedHandle<FileEntry> obj(new FileEntry());
obj->setOffset(offset);
- std::deque<SharedHandle<FileEntry> >::const_iterator i =
+ std::vector<SharedHandle<FileEntry> >::const_iterator i =
std::upper_bound(_fileEntries.begin(), _fileEntries.end(), obj);
if(i != _fileEntries.end() && (*i)->getOffset() == offset) {
return *i;
@@ -103,4 +104,65 @@ DownloadContext::findFileEntryByOffset(off_t offset) const
}
}
+void DownloadContext::setFilePathWithIndex
+(size_t index, const std::string& path)
+{
+ if(0 < index && index <= _fileEntries.size()) {
+ _fileEntries[index-1]->setPath(path);
+ } else {
+ throw DL_ABORT_EX(StringFormat("No such file with index=%u",
+ static_cast<unsigned int>(index)).str());
+ }
+}
+
+void DownloadContext::setFileFilter(IntSequence seq)
+{
+ std::deque<int32_t> fileIndexes = seq.flush();
+ std::sort(fileIndexes.begin(), fileIndexes.end());
+ fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()),
+ fileIndexes.end());
+
+ bool selectAll = fileIndexes.empty() || _fileEntries.size() == 1;
+
+ int32_t index = 1;
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
+ _fileEntries.begin(); i != _fileEntries.end(); ++i, ++index) {
+ (*i)->setRequested
+ (selectAll ||
+ std::binary_search(fileIndexes.begin(), fileIndexes.end(), index));
+ }
+}
+
+void DownloadContext::ensureAttrs()
+{
+ if(_attrs.isNone()) {
+ _attrs = BDE::dict();
+ }
+}
+
+void DownloadContext::setAttribute(const std::string& key, const BDE& value)
+{
+ ensureAttrs();
+ _attrs[key] = value;
+}
+
+BDE& DownloadContext::getAttribute(const std::string& key)
+{
+ ensureAttrs();
+ if(_attrs.containsKey(key)) {
+ return _attrs[key];
+ } else {
+ throw DL_ABORT_EX(StringFormat("No attribute named %s", key.c_str()).str());
+ }
+}
+
+bool DownloadContext::hasAttribute(const std::string& key) const
+{
+ if(_attrs.isNone()) {
+ return false;
+ } else {
+ return _attrs.containsKey(key);
+ }
+}
+
} // namespace aria2
diff --git a/src/DownloadContext.h b/src/DownloadContext.h
index f1aed08e..ef55b035 100644
--- a/src/DownloadContext.h
+++ b/src/DownloadContext.h
@@ -37,80 +37,194 @@
#include "common.h"
+#include <cassert>
#include <string>
-#include <deque>
+#include <vector>
#include "SharedHandle.h"
#include "Signature.h"
#include "TimeA2.h"
+#include "A2STR.h"
+#include "BDE.h"
+#include "IntSequence.h"
namespace aria2 {
class FileEntry;
+class RequestGroup;
class DownloadContext
{
-protected:
- std::deque<SharedHandle<FileEntry> > _fileEntries;
+private:
+ std::vector<SharedHandle<FileEntry> > _fileEntries;
std::string _dir;
-private:
+
+ std::vector<std::string> _pieceHashes;
+
+ size_t _pieceLength;
+
+ std::string _pieceHashAlgo;
+
+ std::string _checksum;
+
+ std::string _checksumHashAlgo;
+
+ std::string _basePath;
+
+ bool _knowsTotalLength;
+
+ RequestGroup* _ownerRequestGroup;
+
+ BDE _attrs;
+
Time _downloadStartTime;
Time _downloadStopTime;
SharedHandle<Signature> _signature;
+
+ void ensureAttrs();
public:
DownloadContext();
- virtual ~DownloadContext();
-
- enum FILE_MODE {
- SINGLE,
- MULTI
- };
+ // Convenient constructor that creates single file download.
+ DownloadContext(size_t pieceLength,
+ uint64_t totalLength,
+ const std::string& path = A2STR::NIL);
- virtual const std::string& getPieceHash(size_t index) const = 0;
+ const std::string& getPieceHash(size_t index) const
+ {
+ if(index < _pieceHashes.size()) {
+ return _pieceHashes[index];
+ } else {
+ return A2STR::NIL;
+ }
+ }
- virtual const std::deque<std::string>& getPieceHashes() const = 0;
+ const std::vector<std::string>& getPieceHashes() const
+ {
+ return _pieceHashes;
+ }
+
+ template<typename InputIterator>
+ void setPieceHashes(InputIterator first, InputIterator last)
+ {
+ _pieceHashes.assign(first, last);
+ }
- virtual uint64_t getTotalLength() const = 0;
+ uint64_t getTotalLength() const
+ {
+ if(_fileEntries.empty()) {
+ return 0;
+ } else {
+ return _fileEntries.back()->getLastOffset();
+ }
+ }
- virtual bool knowsTotalLength() const = 0;
+ bool knowsTotalLength() const { return _knowsTotalLength; }
- virtual FILE_MODE getFileMode() const = 0;
+ void markTotalLengthIsUnknown() { _knowsTotalLength = false; }
- const std::deque<SharedHandle<FileEntry> >& getFileEntries() const
+ const std::vector<SharedHandle<FileEntry> >& getFileEntries() const
{
return _fileEntries;
}
- virtual size_t getPieceLength() const = 0;
+ const SharedHandle<FileEntry>& getFirstFileEntry() const
+ {
+ assert(!_fileEntries.empty());
+ return _fileEntries[0];
+ }
+
+ template<typename InputIterator>
+ void setFileEntries(InputIterator first, InputIterator last)
+ {
+ _fileEntries.assign(first, last);
+ }
+
+ size_t getPieceLength() const { return _pieceLength; }
+
+ void setPieceLength(size_t length) { _pieceLength = length; }
+
+ size_t getNumPieces() const
+ {
+ if(_pieceLength == 0) {
+ return 0;
+ } else {
+ assert(!_fileEntries.empty());
+ return (_fileEntries.back()->getLastOffset()+_pieceLength-1)/_pieceLength;
+ }
+ }
+
+ const std::string& getPieceHashAlgo() const { return _pieceHashAlgo; }
+
+ void setPieceHashAlgo(const std::string& algo)
+ {
+ _pieceHashAlgo = algo;
+ }
+
+ const std::string& getChecksum() const { return _checksum; }
+
+ void setChecksum(const std::string& checksum)
+ {
+ _checksum = checksum;
+ }
+
+ const std::string& getChecksumHashAlgo() const { return _checksumHashAlgo; }
- virtual size_t getNumPieces() const = 0;
+ void setChecksumHashAlgo(const std::string& algo)
+ {
+ _checksumHashAlgo = algo;
+ }
+
+ // The representative path name for this context. It is used as a
+ // part of .aria2 control file. If _basePath is set, returns
+ // _basePath. Otherwise, the first FileEntry's getFilePath() is
+ // returned.
+ const std::string& getBasePath() const
+ {
+ if(_basePath.empty()) {
+ assert(!_fileEntries.empty());
+ return getFirstFileEntry()->getPath();
+ } else {
+ return _basePath;
+ }
+ }
+
+ void setBasePath(const std::string& basePath) { _basePath = basePath; }
+
+ const std::string& getDir() const { return _dir; }
- virtual const std::string& getPieceHashAlgo() const = 0;
+ void setDir(const std::string& dir) { _dir = dir; }
- /**
- * Returns an actual file path.
- * If this contains a single file entry, then returns its file path,
- * for example, "/tmp/downloads/aria2.txt"
- * If this contains multiple file entries(i,e /tmp/downloads/aria2.txt,
- * /tmp/downloads/aria2.bin), then returns its base dir path,
- * for example, "/tmp/downloads"
- */
- virtual std::string getActualBasePath() const = 0;
+ SharedHandle<Signature> getSignature() const { return _signature; }
- const std::string& getDir() const
+ void setSignature(const SharedHandle<Signature>& signature)
{
- return _dir;
+ _signature = signature;
}
- void setDir(const std::string& dir);
+ RequestGroup* getOwnerRequestGroup() { return _ownerRequestGroup; }
- SharedHandle<Signature> getSignature() const;
+ void setOwnerRequestGroup(RequestGroup* owner)
+ {
+ _ownerRequestGroup = owner;
+ }
+
+ void setFileFilter(IntSequence seq);
+
+ // Sets file path for spcified index. index starts from 1. The index
+ // is the same used in setFileFilter(). Please note that path is
+ // not the actual file path. The actual file path is
+ // getDir()+"/"+path.
+ void setFilePathWithIndex(size_t index, const std::string& path);
- void setSignature(const SharedHandle<Signature>& signature);
+ void setAttribute(const std::string& key, const BDE& value);
+
+ BDE& getAttribute(const std::string& key);
+
+ bool hasAttribute(const std::string& key) const;
void resetDownloadStartTime();
@@ -123,8 +237,6 @@ public:
SharedHandle<FileEntry> findFileEntryByOffset(off_t offset) const;
};
-typedef SharedHandle<DownloadContext> DownloadContextHandle;
-
} // namespace aria2
#endif // _D_DOWNLOAD_CONTEXT_H_
diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc
index 5808e426..75c507f2 100644
--- a/src/DownloadEngine.cc
+++ b/src/DownloadEngine.cc
@@ -65,14 +65,15 @@
#include "Command.h"
#include "FileAllocationEntry.h"
#include "CheckIntegrityEntry.h"
-
-#include "BtRegistry.h"
-#include "BtContext.h"
-#include "PeerStorage.h"
-#include "PieceStorage.h"
-#include "BtAnnounce.h"
-#include "BtRuntime.h"
#include "BtProgressInfoFile.h"
+#include "DownloadContext.h"
+#ifdef ENABLE_BITTORRENT
+# include "BtRegistry.h"
+# include "PeerStorage.h"
+# include "PieceStorage.h"
+# include "BtAnnounce.h"
+# include "BtRuntime.h"
+#endif // ENABLE_BITTORRENT
namespace aria2 {
diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc
index b55b158a..0f83a674 100644
--- a/src/DownloadEngineFactory.cc
+++ b/src/DownloadEngineFactory.cc
@@ -57,6 +57,7 @@
#include "DownloadResult.h"
#include "ServerStatMan.h"
#include "a2io.h"
+#include "DownloadContext.h"
#ifdef HAVE_EPOLL
# include "EpollEventPoll.h"
#endif // HAVE_EPOLL
diff --git a/src/DownloadHandler.cc b/src/DownloadHandler.cc
index 93b901d4..8840a630 100644
--- a/src/DownloadHandler.cc
+++ b/src/DownloadHandler.cc
@@ -37,6 +37,7 @@
#include "Logger.h"
#include "RequestGroup.h"
#include "RequestGroupCriteria.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/DownloadResult.h b/src/DownloadResult.h
index 973095ee..d52c79dc 100644
--- a/src/DownloadResult.h
+++ b/src/DownloadResult.h
@@ -40,7 +40,7 @@
#include <stdint.h>
#include <string>
-#include <deque>
+#include <vector>
#include "SharedHandle.h"
#include "FileEntry.h"
@@ -64,7 +64,7 @@ public:
int32_t gid;
- std::deque<SharedHandle<FileEntry> > fileEntries;
+ std::vector<SharedHandle<FileEntry> > fileEntries;
bool inMemoryDownload;
@@ -82,7 +82,7 @@ public:
RESULT result;
DownloadResult(int32_t gid,
- const std::deque<SharedHandle<FileEntry> >& fileEntries,
+ const std::vector<SharedHandle<FileEntry> >& fileEntries,
bool inMemoryDownload,
uint64_t totalLength,
const std::string& uri,
diff --git a/src/FileAllocationCommand.cc b/src/FileAllocationCommand.cc
index db4967a2..1f0eda1a 100644
--- a/src/FileAllocationCommand.cc
+++ b/src/FileAllocationCommand.cc
@@ -42,6 +42,7 @@
#include "prefs.h"
#include "Util.h"
#include "DownloadEngine.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -78,7 +79,8 @@ bool FileAllocationCommand::handleException(Exception& e)
{
_e->_fileAllocationMan->dropPickedEntry();
logger->error(MSG_FILE_ALLOCATION_FAILURE, e, cuid);
- logger->error(MSG_DOWNLOAD_NOT_COMPLETE, cuid, _requestGroup->getFilePath().c_str());
+ logger->error(MSG_DOWNLOAD_NOT_COMPLETE, cuid,
+ _requestGroup->getDownloadContext()->getBasePath().c_str());
return true;
}
diff --git a/src/FileAllocationDispatcherCommand.cc b/src/FileAllocationDispatcherCommand.cc
index ba33aa0b..c86f26cb 100644
--- a/src/FileAllocationDispatcherCommand.cc
+++ b/src/FileAllocationDispatcherCommand.cc
@@ -37,6 +37,7 @@
#include "FileAllocationCommand.h"
#include "message.h"
#include "Logger.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FileAllocationEntry.cc b/src/FileAllocationEntry.cc
index 6a6cd732..aba0b0c5 100644
--- a/src/FileAllocationEntry.cc
+++ b/src/FileAllocationEntry.cc
@@ -38,6 +38,7 @@
#include "RequestGroup.h"
#include "PieceStorage.h"
#include "DiskAdaptor.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FileEntry.h b/src/FileEntry.h
index 05ba6067..a40be12e 100644
--- a/src/FileEntry.h
+++ b/src/FileEntry.h
@@ -60,6 +60,7 @@ private:
bool requested;
std::deque<SharedHandle<Request> > _requestPool;
std::deque<SharedHandle<Request> > _inFlightRequests;
+ std::string _contentType;
public:
FileEntry():length(0), offset(0), extracted(false), requested(false) {}
@@ -128,6 +129,13 @@ public:
// Inserts _uris and _spentUris into uris.
void getUris(std::deque<std::string>& uris) const;
+ void setContentType(const std::string& contentType)
+ {
+ _contentType = contentType;
+ }
+
+ const std::string& getContentType() const { return _contentType; }
+
std::string selectUri(const SharedHandle<URISelector>& uriSelector);
// If pooled Request object is available, one of them is removed
diff --git a/src/FillRequestGroupCommand.cc b/src/FillRequestGroupCommand.cc
index 869496b5..1a544b72 100644
--- a/src/FillRequestGroupCommand.cc
+++ b/src/FillRequestGroupCommand.cc
@@ -39,6 +39,7 @@
#include "RecoverableException.h"
#include "message.h"
#include "Logger.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FtpDownloadCommand.cc b/src/FtpDownloadCommand.cc
index 49a62b5c..d66c0f20 100644
--- a/src/FtpDownloadCommand.cc
+++ b/src/FtpDownloadCommand.cc
@@ -43,6 +43,7 @@
#include "FtpFinishDownloadCommand.h"
#include "FtpConnection.h"
#include "Logger.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FtpFinishDownloadCommand.cc b/src/FtpFinishDownloadCommand.cc
index bf8af2a2..dbf56edc 100644
--- a/src/FtpFinishDownloadCommand.cc
+++ b/src/FtpFinishDownloadCommand.cc
@@ -47,6 +47,7 @@
#include "SocketCore.h"
#include "RequestGroup.h"
#include "Logger.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FtpInitiateConnectionCommand.cc b/src/FtpInitiateConnectionCommand.cc
index 7453337a..dcfcde6b 100644
--- a/src/FtpInitiateConnectionCommand.cc
+++ b/src/FtpInitiateConnectionCommand.cc
@@ -50,6 +50,7 @@
#include "prefs.h"
#include "HttpConnection.h"
#include "Socket.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc
index cbdea101..555ea605 100644
--- a/src/FtpNegotiationCommand.cc
+++ b/src/FtpNegotiationCommand.cc
@@ -53,7 +53,7 @@
#include "Option.h"
#include "Logger.h"
#include "Segment.h"
-#include "SingleFileDownloadContext.h"
+#include "DownloadContext.h"
#include "DefaultBtProgressInfoFile.h"
#include "RequestGroupMan.h"
#include "DownloadFailureException.h"
@@ -328,17 +328,17 @@ bool FtpNegotiationCommand::sendSize() {
bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
{
- SingleFileDownloadContextHandle dctx =
- dynamic_pointer_cast<SingleFileDownloadContext>(_requestGroup->getDownloadContext());
- dctx->setTotalLength(totalLength);
_fileEntry->setLength(totalLength);
- dctx->setFilename
- (strconcat(dctx->getDir(), "/", Util::urldecode(req->getFile())));
+ if(getOption()->get(PREF_OUT).empty()) {
+ _fileEntry->setPath
+ (strconcat(getDownloadContext()->getDir(),
+ "/", Util::urldecode(req->getFile())));
+ }
_requestGroup->preDownloadProcessing();
if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(EX_DUPLICATE_FILE_DOWNLOAD,
- _requestGroup->getFilePath().c_str()).str());
+ _requestGroup->getFirstFilePath().c_str()).str());
}
if(totalLength == 0) {
@@ -361,7 +361,7 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
_requestGroup->getGID(),
- _requestGroup->getFilePath().c_str());
+ _requestGroup->getFirstFilePath().c_str());
poolConnection();
@@ -372,7 +372,7 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
_requestGroup->initPieceStorage();
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
- if(dctx->knowsTotalLength()) {
+ if(getDownloadContext()->knowsTotalLength()) {
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
poolConnection();
return false;
@@ -400,7 +400,7 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
_requestGroup->getGID(),
- _requestGroup->getFilePath().c_str());
+ _requestGroup->getFirstFilePath().c_str());
poolConnection();
@@ -444,10 +444,7 @@ bool FtpNegotiationCommand::recvSize() {
// command, resuming and segmented downloading are disabled when the first
// contacted FTP server doesn't support it.
if(_requestGroup->getPieceStorage().isNull()) {
- SingleFileDownloadContextHandle dctx =
- dynamic_pointer_cast<SingleFileDownloadContext>
- (_requestGroup->getDownloadContext());
- dctx->markTotalLengthIsUnknown();
+ getDownloadContext()->markTotalLengthIsUnknown();
return onFileSizeDetermined(0);
}
diff --git a/src/FtpTunnelRequestCommand.cc b/src/FtpTunnelRequestCommand.cc
index 09a162c5..73e5ed9c 100644
--- a/src/FtpTunnelRequestCommand.cc
+++ b/src/FtpTunnelRequestCommand.cc
@@ -36,6 +36,7 @@
#include "FtpTunnelResponseCommand.h"
#include "Request.h"
#include "Socket.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/FtpTunnelResponseCommand.cc b/src/FtpTunnelResponseCommand.cc
index 293b88c8..0ecb3bd0 100644
--- a/src/FtpTunnelResponseCommand.cc
+++ b/src/FtpTunnelResponseCommand.cc
@@ -39,6 +39,7 @@
#include "HttpRequest.h"
#include "Segment.h"
#include "Socket.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HandshakeExtensionMessage.cc b/src/HandshakeExtensionMessage.cc
index d276b8d9..370746f4 100644
--- a/src/HandshakeExtensionMessage.cc
+++ b/src/HandshakeExtensionMessage.cc
@@ -34,7 +34,6 @@
/* copyright --> */
#include "HandshakeExtensionMessage.h"
#include "Peer.h"
-#include "BtContext.h"
#include "Util.h"
#include "DlAbortEx.h"
#include "LogFactory.h"
@@ -107,11 +106,6 @@ void HandshakeExtensionMessage::setPeer(const PeerHandle& peer)
_peer = peer;
}
-void HandshakeExtensionMessage::setBtContext(const BtContextHandle& btContext)
-{
- _btContext = btContext;
-}
-
uint8_t HandshakeExtensionMessage::getExtensionMessageID(const std::string& name) const
{
std::map<std::string, uint8_t>::const_iterator i = _extensions.find(name);
diff --git a/src/HandshakeExtensionMessage.h b/src/HandshakeExtensionMessage.h
index dc054f52..3c9c7dd9 100644
--- a/src/HandshakeExtensionMessage.h
+++ b/src/HandshakeExtensionMessage.h
@@ -43,7 +43,6 @@
namespace aria2 {
-class BtContext;
class Peer;
class Logger;
class HandshakeExtensionMessage;
@@ -57,8 +56,6 @@ private:
std::map<std::string, uint8_t> _extensions;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<Peer> _peer;
Logger* _logger;
@@ -120,8 +117,6 @@ public:
void setPeer(const SharedHandle<Peer>& peer);
- void setBtContext(const SharedHandle<BtContext>& btContext);
-
static HandshakeExtensionMessageHandle create(const unsigned char* data,
size_t dataLength);
};
diff --git a/src/HaveEraseCommand.cc b/src/HaveEraseCommand.cc
index 4ad39505..910ee761 100644
--- a/src/HaveEraseCommand.cc
+++ b/src/HaveEraseCommand.cc
@@ -37,6 +37,7 @@
#include "RequestGroupMan.h"
#include "PieceStorage.h"
#include "RequestGroup.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpDownloadCommand.cc b/src/HttpDownloadCommand.cc
index 9819efea..98ada9eb 100644
--- a/src/HttpDownloadCommand.cc
+++ b/src/HttpDownloadCommand.cc
@@ -46,6 +46,7 @@
#include "HttpResponse.h"
#include "HttpHeader.h"
#include "Range.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpInitiateConnectionCommand.cc b/src/HttpInitiateConnectionCommand.cc
index b9552db5..4245403a 100644
--- a/src/HttpInitiateConnectionCommand.cc
+++ b/src/HttpInitiateConnectionCommand.cc
@@ -47,6 +47,7 @@
#include "message.h"
#include "prefs.h"
#include "A2STR.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpProxyRequestCommand.cc b/src/HttpProxyRequestCommand.cc
index 9d0a434b..04e534ee 100644
--- a/src/HttpProxyRequestCommand.cc
+++ b/src/HttpProxyRequestCommand.cc
@@ -36,6 +36,7 @@
#include "HttpProxyResponseCommand.h"
#include "Request.h"
#include "Socket.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpProxyResponseCommand.cc b/src/HttpProxyResponseCommand.cc
index 0054d6d9..be6a58ff 100644
--- a/src/HttpProxyResponseCommand.cc
+++ b/src/HttpProxyResponseCommand.cc
@@ -39,6 +39,7 @@
#include "HttpRequest.h"
#include "Segment.h"
#include "Socket.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc
index d46f68ac..bac87114 100644
--- a/src/HttpRequest.cc
+++ b/src/HttpRequest.cc
@@ -53,8 +53,7 @@ namespace aria2 {
const std::string HttpRequest::USER_AGENT("aria2");
-HttpRequest::HttpRequest():entityLength(0),
- _contentEncodingEnabled(true),
+HttpRequest::HttpRequest():_contentEncodingEnabled(true),
userAgent(USER_AGENT)
{}
@@ -83,7 +82,8 @@ off_t HttpRequest::getEndByte() const
return 0;
} else {
if(request->isPipeliningEnabled()) {
- return _fileEntry->gtoloff(segment->getPosition()+segment->getLength()-1);
+ off_t endByte = _fileEntry->gtoloff(segment->getPosition()+segment->getLength()-1);
+ return std::min(endByte, _fileEntry->getLastOffset()-1);
} else {
return 0;
}
@@ -96,7 +96,8 @@ RangeHandle HttpRequest::getRange() const
if(segment.isNull()) {
return SharedHandle<Range>(new Range());
} else {
- return SharedHandle<Range>(new Range(getStartByte(), getEndByte(), entityLength));
+ return SharedHandle<Range>(new Range(getStartByte(), getEndByte(),
+ _fileEntry->getLength()));
}
}
@@ -107,9 +108,9 @@ bool HttpRequest::isRangeSatisfied(const RangeHandle& range) const
}
if((getStartByte() == range->getStartByte()) &&
((getEndByte() == 0) ||
- ((getEndByte() > 0) && (getEndByte() == range->getEndByte()))) &&
- ((entityLength == 0) ||
- ((entityLength > 0) && (entityLength == range->getEntityLength())))) {
+ (getEndByte() == range->getEndByte())) &&
+ ((_fileEntry->getLength() == 0) ||
+ (_fileEntry->getLength() == range->getEntityLength()))) {
return true;
} else {
return false;
diff --git a/src/HttpRequest.h b/src/HttpRequest.h
index 9ec32171..def1ddd6 100644
--- a/src/HttpRequest.h
+++ b/src/HttpRequest.h
@@ -37,6 +37,7 @@
#include "common.h"
+#include <cassert>
#include <string>
#include <deque>
@@ -64,8 +65,6 @@ private:
SharedHandle<Segment> segment;
- uint64_t entityLength;
-
bool _contentEncodingEnabled;
std::string userAgent;
@@ -97,17 +96,10 @@ public:
void setRequest(const SharedHandle<Request>& request);
- /**
- * entityLength is used in isRangeSatisfied() method.
- */
- void setEntityLength(uint64_t entityLength)
- {
- this->entityLength = entityLength;
- }
-
uint64_t getEntityLength() const
{
- return entityLength;
+ assert(!_fileEntry.isNull());
+ return _fileEntry->getLength();
}
const std::string& getHost() const
diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc
index d95e616b..961e8155 100644
--- a/src/HttpRequestCommand.cc
+++ b/src/HttpRequestCommand.cc
@@ -52,6 +52,7 @@
#include "CookieStorage.h"
#include "AuthConfigFactory.h"
#include "AuthConfig.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -89,7 +90,6 @@ createHttpRequest(const SharedHandle<Request>& req,
httpRequest->setRequest(req);
httpRequest->setFileEntry(fileEntry);
httpRequest->setSegment(segment);
- httpRequest->setEntityLength(fileEntry->getLength());
httpRequest->addHeader(option->get(PREF_HEADER));
httpRequest->setCookieStorage(cookieStorage);
httpRequest->setAuthConfigFactory(authConfigFactory);
diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc
index 30de2641..ece2606a 100644
--- a/src/HttpResponseCommand.cc
+++ b/src/HttpResponseCommand.cc
@@ -34,7 +34,7 @@
/* copyright --> */
#include "HttpResponseCommand.h"
#include "DownloadEngine.h"
-#include "SingleFileDownloadContext.h"
+#include "DownloadContext.h"
#include "FileEntry.h"
#include "RequestGroup.h"
#include "ServerHost.h"
@@ -136,18 +136,20 @@ bool HttpResponseCommand::executeInternal()
}
if(_requestGroup->getPieceStorage().isNull()) {
uint64_t totalLength = httpResponse->getEntityLength();
- SingleFileDownloadContextHandle dctx =
- dynamic_pointer_cast<SingleFileDownloadContext>(_requestGroup->getDownloadContext());
- dctx->setTotalLength(totalLength);
_fileEntry->setLength(totalLength);
- dctx->setFilename
- (strconcat(dctx->getDir(), "/", httpResponse->determinFilename()));
- dctx->setContentType(httpResponse->getContentType());
+ // We assume that in this context
+ // DownloadContext::getFileEntries().size() == 1
+ if(getOption()->get(PREF_OUT).empty()) {
+ _fileEntry->setPath
+ (strconcat(getDownloadContext()->getDir(),
+ "/", httpResponse->determinFilename()));
+ }
+ _fileEntry->setContentType(httpResponse->getContentType());
_requestGroup->preDownloadProcessing();
if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(EX_DUPLICATE_FILE_DOWNLOAD,
- _requestGroup->getFilePath().c_str()).str());
+ _requestGroup->getFirstFilePath().c_str()).str());
}
// update last modified time
updateLastModifiedTime(httpResponse->getLastModifiedTime());
@@ -156,13 +158,13 @@ bool HttpResponseCommand::executeInternal()
// assume we can do segmented downloading
if(totalLength == 0 || shouldInflateContentEncoding(httpResponse)) {
// we ignore content-length when inflate is required
- dctx->setTotalLength(0);
+ _fileEntry->setLength(0);
if(req->getMethod() == Request::METHOD_GET &&
(totalLength != 0 ||
!httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
- // dctx->knowsTotalLength() == true only when server says the
- // size of file is 0 explicitly.
- dctx->markTotalLengthIsUnknown();
+ // DownloadContext::knowsTotalLength() == true only when
+ // server says the size of file is 0 explicitly.
+ getDownloadContext()->markTotalLengthIsUnknown();
}
return handleOtherEncoding(httpResponse);
} else {
@@ -241,7 +243,7 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
_requestGroup->getGID(),
- _requestGroup->getFilePath().c_str());
+ _requestGroup->getFirstFilePath().c_str());
return true;
}
@@ -249,7 +251,7 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
DownloadCommand* command = 0;
try {
_requestGroup->loadAndOpenFile(infoFile);
- File file(_requestGroup->getFilePath());
+ File file(_requestGroup->getFirstFilePath());
SegmentHandle segment = _requestGroup->getSegmentMan()->getSegment(cuid, 0);
// pipelining requires implicit range specified. But the request for
@@ -335,7 +337,7 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
_requestGroup->getGID(),
- _requestGroup->getFilePath().c_str());
+ _requestGroup->getFirstFilePath().c_str());
poolConnection();
return true;
diff --git a/src/HttpServerBodyCommand.cc b/src/HttpServerBodyCommand.cc
index afbf601d..c40efde1 100644
--- a/src/HttpServerBodyCommand.cc
+++ b/src/HttpServerBodyCommand.cc
@@ -49,6 +49,7 @@
#include "XmlRpcMethod.h"
#include "XmlRpcMethodFactory.h"
#include "XmlRpcResponse.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpServerCommand.cc b/src/HttpServerCommand.cc
index 55f32427..38b9bdee 100644
--- a/src/HttpServerCommand.cc
+++ b/src/HttpServerCommand.cc
@@ -46,6 +46,7 @@
#include "prefs.h"
#include "Option.h"
#include "Util.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc
index b9edb717..ff1bf174 100644
--- a/src/HttpSkipResponseCommand.cc
+++ b/src/HttpSkipResponseCommand.cc
@@ -53,6 +53,7 @@
#include "CookieStorage.h"
#include "AuthConfigFactory.h"
#include "AuthConfig.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/InitiateConnectionCommandFactory.cc b/src/InitiateConnectionCommandFactory.cc
index 2ad3dbda..450f6d46 100644
--- a/src/InitiateConnectionCommandFactory.cc
+++ b/src/InitiateConnectionCommandFactory.cc
@@ -43,6 +43,7 @@
#include "Option.h"
#include "prefs.h"
#include "SocketCore.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/InitiatorMSEHandshakeCommand.cc b/src/InitiatorMSEHandshakeCommand.cc
index b29fe38c..7afeab6e 100644
--- a/src/InitiatorMSEHandshakeCommand.cc
+++ b/src/InitiatorMSEHandshakeCommand.cc
@@ -43,7 +43,6 @@
#include "Logger.h"
#include "Peer.h"
#include "PeerConnection.h"
-#include "BtContext.h"
#include "BtRuntime.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
@@ -52,6 +51,8 @@
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
#include "RequestGroup.h"
+#include "DownloadContext.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -60,13 +61,11 @@ InitiatorMSEHandshakeCommand::InitiatorMSEHandshakeCommand
RequestGroup* requestGroup,
const SharedHandle<Peer>& p,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<SocketCore>& s):
PeerAbstractCommand(cuid, p, e, s),
_requestGroup(requestGroup),
- _btContext(btContext),
_btRuntime(btRuntime),
_sequence(INITIATOR_SEND_KEY),
_mseHandshake(new MSEHandshake(cuid, socket, getOption().get()))
@@ -114,7 +113,8 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
break;
case INITIATOR_WAIT_KEY: {
if(_mseHandshake->receivePublicKey()) {
- _mseHandshake->initCipher(_btContext->getInfoHash());
+ _mseHandshake->initCipher
+ (bittorrent::getInfoHash(_requestGroup->getDownloadContext()));;
if(_mseHandshake->sendInitiatorStep2()) {
_sequence = INITIATOR_FIND_VC_MARKER;
} else {
@@ -151,11 +151,11 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
_mseHandshake->getDecryptor());
}
PeerInteractionCommand* c =
- new PeerInteractionCommand(cuid, _requestGroup, peer, e, _btContext,
- _btRuntime, _pieceStorage,
- socket,
- PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE,
- peerConnection);
+ new PeerInteractionCommand
+ (cuid, _requestGroup, peer, e, _btRuntime, _pieceStorage,
+ socket,
+ PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE,
+ peerConnection);
c->setPeerStorage(_peerStorage);
e->commands.push_back(c);
return true;
@@ -176,7 +176,7 @@ bool InitiatorMSEHandshakeCommand::prepareForNextPeer(time_t wait)
peer->usedBy(e->newCUID());
PeerInitiateConnectionCommand* command =
new PeerInitiateConnectionCommand(peer->usedBy(), _requestGroup, peer,
- e, _btContext, _btRuntime);
+ e, _btRuntime);
command->setPeerStorage(_peerStorage);
command->setPieceStorage(_pieceStorage);
e->commands.push_back(command);
@@ -187,7 +187,7 @@ bool InitiatorMSEHandshakeCommand::prepareForNextPeer(time_t wait)
logger->info("CUID#%d - Retry using legacy BitTorrent handshake.", cuid);
PeerInitiateConnectionCommand* command =
new PeerInitiateConnectionCommand(cuid, _requestGroup, peer, e,
- _btContext, _btRuntime, false);
+ _btRuntime, false);
command->setPeerStorage(_peerStorage);
command->setPieceStorage(_pieceStorage);
e->commands.push_back(command);
diff --git a/src/InitiatorMSEHandshakeCommand.h b/src/InitiatorMSEHandshakeCommand.h
index 46cbedf0..996a72e9 100644
--- a/src/InitiatorMSEHandshakeCommand.h
+++ b/src/InitiatorMSEHandshakeCommand.h
@@ -40,7 +40,6 @@
namespace aria2 {
class RequestGroup;
-class BtContext;
class PeerStorage;
class PieceStorage;
class BtRuntime;
@@ -61,8 +60,6 @@ public:
private:
RequestGroup* _requestGroup;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<PieceStorage> _pieceStorage;
@@ -79,13 +76,13 @@ protected:
virtual void onAbort();
virtual bool exitBeforeExecute();
public:
- InitiatorMSEHandshakeCommand(int32_t cuid,
- RequestGroup* requestGroup,
- const SharedHandle<Peer>& peer,
- DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
- const SharedHandle<BtRuntime>& btRuntime,
- const SharedHandle<SocketCore>& s);
+ InitiatorMSEHandshakeCommand
+ (int32_t cuid,
+ RequestGroup* requestGroup,
+ const SharedHandle<Peer>& peer,
+ DownloadEngine* e,
+ const SharedHandle<BtRuntime>& btRuntime,
+ const SharedHandle<SocketCore>& s);
virtual ~InitiatorMSEHandshakeCommand();
diff --git a/src/IteratableChecksumValidator.cc b/src/IteratableChecksumValidator.cc
index b250af4d..a3be0a21 100644
--- a/src/IteratableChecksumValidator.cc
+++ b/src/IteratableChecksumValidator.cc
@@ -38,7 +38,6 @@
#include "Util.h"
#include "message.h"
-#include "SingleFileDownloadContext.h"
#include "PieceStorage.h"
#include "messageDigest.h"
#include "LogFactory.h"
@@ -46,14 +45,16 @@
#include "DiskAdaptor.h"
#include "FileEntry.h"
#include "BitfieldMan.h"
+#include "DownloadContext.h"
namespace aria2 {
#define BUFSIZE (256*1024)
#define ALIGNMENT 512
-IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
- const PieceStorageHandle& pieceStorage):
+IteratableChecksumValidator::IteratableChecksumValidator
+(const SharedHandle<DownloadContext>& dctx,
+ const PieceStorageHandle& pieceStorage):
_dctx(dctx),
_pieceStorage(pieceStorage),
_currentOffset(0),
diff --git a/src/IteratableChecksumValidator.h b/src/IteratableChecksumValidator.h
index 2a8997a8..62112e95 100644
--- a/src/IteratableChecksumValidator.h
+++ b/src/IteratableChecksumValidator.h
@@ -39,7 +39,7 @@
namespace aria2 {
-class SingleFileDownloadContext;
+class DownloadContext;
class PieceStorage;
class Logger;
class MessageDigestContext;
@@ -47,7 +47,7 @@ class MessageDigestContext;
class IteratableChecksumValidator:public IteratableValidator
{
private:
- SharedHandle<SingleFileDownloadContext> _dctx;
+ SharedHandle<DownloadContext> _dctx;
SharedHandle<PieceStorage> _pieceStorage;
@@ -60,7 +60,7 @@ private:
unsigned char* _buffer;
public:
- IteratableChecksumValidator(const SharedHandle<SingleFileDownloadContext>& dctx,
+ IteratableChecksumValidator(const SharedHandle<DownloadContext>& dctx,
const SharedHandle<PieceStorage>& pieceStorage);
virtual ~IteratableChecksumValidator();
diff --git a/src/IteratableChunkChecksumValidator.cc b/src/IteratableChunkChecksumValidator.cc
index bb3f2fcb..b58ab90d 100644
--- a/src/IteratableChunkChecksumValidator.cc
+++ b/src/IteratableChunkChecksumValidator.cc
@@ -58,7 +58,7 @@ namespace aria2 {
#define ALIGNMENT 512
IteratableChunkChecksumValidator::
-IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
+IteratableChunkChecksumValidator(const SharedHandle<DownloadContext>& dctx,
const PieceStorageHandle& pieceStorage):
_dctx(dctx),
_pieceStorage(pieceStorage),
@@ -153,7 +153,7 @@ std::string IteratableChunkChecksumValidator::digest(off_t offset, size_t length
curoffset);
if(r == 0 || r < static_cast<size_t>(woffset)) {
throw DL_ABORT_EX
- (StringFormat(EX_FILE_READ, _dctx->getActualBasePath().c_str(),
+ (StringFormat(EX_FILE_READ, _dctx->getBasePath().c_str(),
strerror(errno)).str());
}
size_t wlength;
diff --git a/src/MSEHandshake.cc b/src/MSEHandshake.cc
index 70ce2ef7..760002bc 100644
--- a/src/MSEHandshake.cc
+++ b/src/MSEHandshake.cc
@@ -50,10 +50,11 @@
#include "MessageDigestHelper.h"
#include "SimpleRandomizer.h"
#include "Util.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "prefs.h"
#include "Option.h"
#include "StringFormat.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -435,7 +436,7 @@ bool MSEHandshake::findReceiverHashMarker()
}
bool MSEHandshake::receiveReceiverHashAndPadCLength
-(const std::deque<SharedHandle<BtContext> >& btContexts)
+(const std::deque<SharedHandle<DownloadContext> >& downloadContexts)
{
size_t r = 20+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2/*PadC length*/-_rbufLength;
if(r > receiveNBytes(r)) {
@@ -444,22 +445,23 @@ bool MSEHandshake::receiveReceiverHashAndPadCLength
// resolve info hash
// pointing to the position of HASH('req2', SKEY) xor HASH('req3', S)
unsigned char* rbufptr = _rbuf;
- SharedHandle<BtContext> btContext;
- for(std::deque<SharedHandle<BtContext> >::const_iterator i = btContexts.begin();
- i != btContexts.end(); ++i) {
+ SharedHandle<DownloadContext> downloadContext;
+ for(std::deque<SharedHandle<DownloadContext> >::const_iterator i =
+ downloadContexts.begin(); i != downloadContexts.end(); ++i) {
unsigned char md[20];
- createReq23Hash(md, (*i)->getInfoHash());
+ const BDE& torrentAttrs = (*i)->getAttribute(bittorrent::BITTORRENT);
+ createReq23Hash(md, torrentAttrs[bittorrent::INFO_HASH].uc());
if(memcmp(md, rbufptr, sizeof(md)) == 0) {
- _logger->debug("CUID#%d - info hash found: %s", _cuid, (*i)->getInfoHashAsString().c_str());
- btContext = *i;
+ _logger->debug("CUID#%d - info hash found: %s", _cuid,
+ Util::toHex(torrentAttrs[bittorrent::INFO_HASH].s()).c_str());
+ downloadContext = *i;
break;
}
}
- if(btContext.isNull()) {
+ if(downloadContext.isNull()) {
throw DL_ABORT_EX("Unknown info hash.");
}
- initCipher(btContext->getInfoHash());
-
+ initCipher(bittorrent::getInfoHash(downloadContext));
// decrypt VC
rbufptr += 20;
verifyVC(rbufptr);
diff --git a/src/MSEHandshake.h b/src/MSEHandshake.h
index f2ceb3a7..14ef0ad3 100644
--- a/src/MSEHandshake.h
+++ b/src/MSEHandshake.h
@@ -51,7 +51,7 @@ class SocketCore;
class DHKeyExchange;
class ARC4Encryptor;
class ARC4Decryptor;
-class BtContext;
+class DownloadContext;
class MSEHandshake {
public:
@@ -158,7 +158,7 @@ public:
bool findReceiverHashMarker();
bool receiveReceiverHashAndPadCLength
- (const std::deque<SharedHandle<BtContext> >& btContexts);
+ (const std::deque<SharedHandle<DownloadContext> >& downloadContexts);
bool receiveReceiverIALength();
diff --git a/src/Makefile.am b/src/Makefile.am
index 5951269f..235befee 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -152,7 +152,6 @@ SRCS = Socket.h\
ByteArrayDiskWriterFactory.cc ByteArrayDiskWriterFactory.h\
ServerHost.cc ServerHost.h\
DownloadContext.cc DownloadContext.h\
- SingleFileDownloadContext.cc SingleFileDownloadContext.h\
TimedHaltCommand.cc TimedHaltCommand.h\
CUIDCounter.h\
DNSCache.h\
@@ -294,8 +293,6 @@ SRCS += PeerMessageUtil.cc PeerMessageUtil.h\
PeerListProcessor.h\
AnnounceTier.h\
AnnounceList.h AnnounceList.cc\
- BtContext.h\
- DefaultBtContext.cc DefaultBtContext.h\
PeerStorage.h\
DefaultPeerStorage.cc DefaultPeerStorage.h\
BtAnnounce.cc BtAnnounce.h\
@@ -436,7 +433,8 @@ SRCS += PeerMessageUtil.cc PeerMessageUtil.h\
RangeBtMessageValidator.h\
IndexBtMessageValidator.h\
ExtensionMessageRegistry.h\
- bencode.cc bencode.h
+ bencode.cc bencode.h\
+ bittorrent_helper.cc bittorrent_helper.h
endif # ENABLE_BITTORRENT
if ENABLE_METALINK
diff --git a/src/Makefile.in b/src/Makefile.in
index f46e2465..09e34803 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -89,8 +89,6 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ PeerListProcessor.h\
@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@ PeerStorage.h\
@ENABLE_BITTORRENT_TRUE@ DefaultPeerStorage.cc DefaultPeerStorage.h\
@ENABLE_BITTORRENT_TRUE@ BtAnnounce.cc BtAnnounce.h\
@@ -231,7 +229,8 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ RangeBtMessageValidator.h\
@ENABLE_BITTORRENT_TRUE@ IndexBtMessageValidator.h\
@ENABLE_BITTORRENT_TRUE@ ExtensionMessageRegistry.h\
-@ENABLE_BITTORRENT_TRUE@ bencode.cc bencode.h
+@ENABLE_BITTORRENT_TRUE@ bencode.cc bencode.h\
+@ENABLE_BITTORRENT_TRUE@ bittorrent_helper.cc bittorrent_helper.h
@ENABLE_METALINK_TRUE@am__append_14 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@@ -400,11 +399,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
PeerConnection.cc PeerConnection.h ByteArrayDiskWriter.cc \
ByteArrayDiskWriter.h ByteArrayDiskWriterFactory.cc \
ByteArrayDiskWriterFactory.h ServerHost.cc ServerHost.h \
- DownloadContext.cc DownloadContext.h \
- SingleFileDownloadContext.cc SingleFileDownloadContext.h \
- TimedHaltCommand.cc TimedHaltCommand.h CUIDCounter.h \
- DNSCache.h DownloadResult.h Sequence.h IntSequence.h \
- PostDownloadHandler.h PreDownloadHandler.h SingletonHolder.h \
+ DownloadContext.cc DownloadContext.h TimedHaltCommand.cc \
+ TimedHaltCommand.h CUIDCounter.h DNSCache.h DownloadResult.h \
+ Sequence.h IntSequence.h PostDownloadHandler.h \
+ PreDownloadHandler.h SingletonHolder.h \
TrueRequestGroupCriteria.h a2algo.h a2functional.h a2io.h \
a2netcompat.h a2time.h array_fun.h help_tags.h prefs.cc \
prefs.h usage_text.h ProtocolDetector.cc ProtocolDetector.h \
@@ -466,8 +464,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
TimeSeedCriteria.h ShareRatioSeedCriteria.h \
UnionSeedCriteria.h SeedCheckCommand.cc SeedCheckCommand.h \
PeerListProcessor.h AnnounceTier.h AnnounceList.h \
- AnnounceList.cc BtContext.h DefaultBtContext.cc \
- DefaultBtContext.h PeerStorage.h DefaultPeerStorage.cc \
+ AnnounceList.cc PeerStorage.h DefaultPeerStorage.cc \
DefaultPeerStorage.h BtAnnounce.cc BtAnnounce.h \
DefaultBtAnnounce.cc DefaultBtAnnounce.h BtRuntime.h \
BtMessage.h AbstractBtMessage.cc AbstractBtMessage.h \
@@ -564,9 +561,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
IndexBtMessage.cc IndexBtMessage.h ZeroBtMessage.cc \
ZeroBtMessage.h RangeBtMessageValidator.h \
IndexBtMessageValidator.h ExtensionMessageRegistry.h \
- bencode.cc bencode.h Metalinker.cc Metalinker.h \
- MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
- MetalinkResource.h MetalinkProcessor.h \
+ bencode.cc bencode.h bittorrent_helper.cc bittorrent_helper.h \
+ Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
+ MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
MetalinkParserController.cc MetalinkParserController.h \
MetalinkParserStateMachine.cc MetalinkParserStateMachine.h \
MetalinkParserState.h InitialMetalinkParserState.cc \
@@ -638,7 +635,6 @@ am__objects_6 =
@ENABLE_BITTORRENT_TRUE@ PeerChokeCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ SeedCheckCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ AnnounceList.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ DefaultBtContext.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultPeerStorage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ BtAnnounce.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultBtAnnounce.$(OBJEXT) \
@@ -734,7 +730,8 @@ am__objects_6 =
@ENABLE_BITTORRENT_TRUE@ RangeBtMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ IndexBtMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ZeroBtMessage.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ bencode.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@ bencode.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ bittorrent_helper.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_14 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
@@ -833,10 +830,9 @@ am__objects_26 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
MultiFileAllocationIterator.$(OBJEXT) PeerConnection.$(OBJEXT) \
ByteArrayDiskWriter.$(OBJEXT) \
ByteArrayDiskWriterFactory.$(OBJEXT) ServerHost.$(OBJEXT) \
- DownloadContext.$(OBJEXT) SingleFileDownloadContext.$(OBJEXT) \
- TimedHaltCommand.$(OBJEXT) prefs.$(OBJEXT) \
- ProtocolDetector.$(OBJEXT) StringFormat.$(OBJEXT) \
- HttpSkipResponseCommand.$(OBJEXT) \
+ DownloadContext.$(OBJEXT) TimedHaltCommand.$(OBJEXT) \
+ prefs.$(OBJEXT) ProtocolDetector.$(OBJEXT) \
+ StringFormat.$(OBJEXT) HttpSkipResponseCommand.$(OBJEXT) \
InitiateConnectionCommand.$(OBJEXT) \
FtpFinishDownloadCommand.$(OBJEXT) A2STR.$(OBJEXT) \
RarestPieceSelector.$(OBJEXT) ChunkedDecoder.$(OBJEXT) \
@@ -1157,11 +1153,10 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
PeerConnection.cc PeerConnection.h ByteArrayDiskWriter.cc \
ByteArrayDiskWriter.h ByteArrayDiskWriterFactory.cc \
ByteArrayDiskWriterFactory.h ServerHost.cc ServerHost.h \
- DownloadContext.cc DownloadContext.h \
- SingleFileDownloadContext.cc SingleFileDownloadContext.h \
- TimedHaltCommand.cc TimedHaltCommand.h CUIDCounter.h \
- DNSCache.h DownloadResult.h Sequence.h IntSequence.h \
- PostDownloadHandler.h PreDownloadHandler.h SingletonHolder.h \
+ DownloadContext.cc DownloadContext.h TimedHaltCommand.cc \
+ TimedHaltCommand.h CUIDCounter.h DNSCache.h DownloadResult.h \
+ Sequence.h IntSequence.h PostDownloadHandler.h \
+ PreDownloadHandler.h SingletonHolder.h \
TrueRequestGroupCriteria.h a2algo.h a2functional.h a2io.h \
a2netcompat.h a2time.h array_fun.h help_tags.h prefs.cc \
prefs.h usage_text.h ProtocolDetector.cc ProtocolDetector.h \
@@ -1393,7 +1388,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultAuthResolver.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)/DefaultBtInteractive.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageDispatcher.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageFactory.Po@am__quote@
@@ -1541,7 +1535,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleRandomizer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingleFileAllocationIterator.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingleFileDownloadContext.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SizeMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SkipTagMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SleepCommand.Po@am__quote@
@@ -1578,6 +1571,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ZeroBtMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asctime_r.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bencode.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bittorrent_helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/download_helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gai_strerror.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getaddrinfo.Po@am__quote@
diff --git a/src/Metalink2RequestGroup.cc b/src/Metalink2RequestGroup.cc
index e8874c8f..1b9a36a4 100644
--- a/src/Metalink2RequestGroup.cc
+++ b/src/Metalink2RequestGroup.cc
@@ -43,7 +43,7 @@
#include "prefs.h"
#include "Util.h"
#include "message.h"
-#include "SingleFileDownloadContext.h"
+#include "DownloadContext.h"
#include "MetalinkHelper.h"
#include "BinaryStream.h"
#include "MemoryBufferPreDownloadHandler.h"
@@ -170,10 +170,11 @@ Metalink2RequestGroup::createRequestGroup
std::deque<std::string> uris;
uris.push_back((*itr)->url);
torrentRg.reset(new RequestGroup(option, uris));
- SharedHandle<SingleFileDownloadContext> dctx
- (new SingleFileDownloadContext(option->getAsInt(PREF_SEGMENT_SIZE),
- 0,
- A2STR::NIL));
+ SharedHandle<DownloadContext> dctx
+ (new DownloadContext(option->getAsInt(PREF_SEGMENT_SIZE),
+ 0,
+ A2STR::NIL));
+ // Since torrent is downloaded in memory, setting dir has no effect.
//dctx->setDir(_option->get(PREF_DIR));
torrentRg->setDownloadContext(dctx);
torrentRg->clearPreDowloadHandler();
@@ -208,11 +209,10 @@ Metalink2RequestGroup::createRequestGroup
#else
pieceLength = option->getAsInt(PREF_SEGMENT_SIZE);
#endif // ENABLE_MESSAGE_DIGEST
- SharedHandle<SingleFileDownloadContext> dctx
- (new SingleFileDownloadContext
+ SharedHandle<DownloadContext> dctx
+ (new DownloadContext
(pieceLength,
entry->getLength(),
- A2STR::NIL,
strconcat(option->get(PREF_DIR), "/", entry->file->getPath())));
dctx->setDir(option->get(PREF_DIR));
#ifdef ENABLE_MESSAGE_DIGEST
@@ -222,7 +222,8 @@ Metalink2RequestGroup::createRequestGroup
dctx->setChecksumHashAlgo(entry->checksum->getAlgo());
}
} else {
- dctx->setPieceHashes(entry->chunkChecksum->getChecksums());
+ dctx->setPieceHashes(entry->chunkChecksum->getChecksums().begin(),
+ entry->chunkChecksum->getChecksums().end());
dctx->setPieceHashAlgo(entry->chunkChecksum->getAlgo());
}
#endif // ENABLE_MESSAGE_DIGEST
diff --git a/src/MetalinkPostDownloadHandler.cc b/src/MetalinkPostDownloadHandler.cc
index 7623f1e8..038a3687 100644
--- a/src/MetalinkPostDownloadHandler.cc
+++ b/src/MetalinkPostDownloadHandler.cc
@@ -62,7 +62,7 @@ void MetalinkPostDownloadHandler::getNextRequestGroups
RequestGroup* requestGroup)
{
_logger->debug("Generating RequestGroups for Metalink file %s",
- requestGroup->getFilePath().c_str());
+ requestGroup->getFirstFilePath().c_str());
SharedHandle<DiskAdaptor> diskAdaptor = requestGroup->getPieceStorage()->getDiskAdaptor();
try {
diskAdaptor->openExistingFile();
diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc
index 7083de7f..729eb676 100644
--- a/src/MultiDiskAdaptor.cc
+++ b/src/MultiDiskAdaptor.cc
@@ -166,7 +166,7 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
return;
}
- for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
fileEntries.begin(); i != fileEntries.end(); ++i) {
diskWriterEntries.push_back
(createDiskWriterEntry(*i, (*i)->isRequested()));
@@ -176,9 +176,9 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
// TODO Currently, pieceLength == 0 is used for unit testing only.
if(pieceLength > 0) {
- std::deque<SharedHandle<DiskWriterEntry> >::iterator done =
+ std::vector<SharedHandle<DiskWriterEntry> >::iterator done =
diskWriterEntries.begin();
- for(std::deque<SharedHandle<DiskWriterEntry> >::iterator itr =
+ for(std::vector<SharedHandle<DiskWriterEntry> >::iterator itr =
diskWriterEntries.begin(); itr != diskWriterEntries.end();) {
const SharedHandle<FileEntry>& fileEntry = (*itr)->getFileEntry();
@@ -189,7 +189,7 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
off_t pieceStartOffset =
(fileEntry->getOffset()/pieceLength)*pieceLength;
if(itr != diskWriterEntries.begin()) {
- for(std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
+ for(std::vector<SharedHandle<DiskWriterEntry> >::iterator i =
itr-1; true; --i) {
const SharedHandle<FileEntry>& fileEntry = (*i)->getFileEntry();
if(pieceStartOffset <= fileEntry->getOffset() ||
@@ -240,7 +240,7 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
}
}
DefaultDiskWriterFactory dwFactory;
- for(std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
+ for(std::vector<SharedHandle<DiskWriterEntry> >::iterator i =
diskWriterEntries.begin(); i != diskWriterEntries.end(); ++i) {
if((*i)->needsFileAllocation() ||
dwreq.find((*i)->getFileEntry()->getPath()) != dwreq.end() ||
@@ -260,7 +260,7 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
void MultiDiskAdaptor::mkdir() const
{
- for(std::deque<SharedHandle<DiskWriterEntry> >::const_iterator i =
+ for(std::vector<SharedHandle<DiskWriterEntry> >::const_iterator i =
diskWriterEntries.begin(); i != diskWriterEntries.end(); ++i) {
(*i)->getFileEntry()->setupDir();
}
@@ -279,7 +279,7 @@ void MultiDiskAdaptor::openIfNot
// Cache is full.
// Choose one DiskWriterEntry randomly and close it.
size_t index = SimpleRandomizer::getInstance()->getRandomNumber(numOpened);
- std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
+ std::vector<SharedHandle<DiskWriterEntry> >::iterator i =
_openedDiskWriterEntries.begin();
std::advance(i, index);
(*i)->closeFile();
@@ -443,7 +443,7 @@ ssize_t MultiDiskAdaptor::readData(unsigned char* data, size_t len, off_t offset
bool MultiDiskAdaptor::fileExists()
{
- for(std::deque<SharedHandle<FileEntry> >::iterator i =
+ for(std::vector<SharedHandle<FileEntry> >::iterator i =
fileEntries.begin(); i != fileEntries.end(); ++i) {
if((*i)->exists()) {
return true;
@@ -455,10 +455,9 @@ bool MultiDiskAdaptor::fileExists()
uint64_t MultiDiskAdaptor::size()
{
uint64_t size = 0;
- for(DiskWriterEntries::const_iterator itr = diskWriterEntries.begin();
- itr != diskWriterEntries.end(); ++itr) {
- openIfNot(*itr, &DiskWriterEntry::openFile);
- size += (*itr)->size();
+ for(std::vector<SharedHandle<FileEntry> >::iterator i =
+ fileEntries.begin(); i != fileEntries.end(); ++i) {
+ size += File((*i)->getPath()).size();
}
return size;
}
@@ -496,7 +495,7 @@ void MultiDiskAdaptor::disableReadOnly()
void MultiDiskAdaptor::cutTrailingGarbage()
{
- for(std::deque<SharedHandle<DiskWriterEntry> >::const_iterator i =
+ for(std::vector<SharedHandle<DiskWriterEntry> >::const_iterator i =
diskWriterEntries.begin(); i != diskWriterEntries.end(); ++i) {
uint64_t length = (*i)->getFileEntry()->getLength();
if(File((*i)->getFilePath()).size() > length) {
@@ -515,7 +514,7 @@ void MultiDiskAdaptor::setMaxOpenFiles(size_t maxOpenFiles)
size_t MultiDiskAdaptor::utime(const Time& actime, const Time& modtime)
{
size_t numOK = 0;
- for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
fileEntries.begin(); i != fileEntries.end(); ++i) {
if((*i)->isRequested()) {
File f((*i)->getPath());
diff --git a/src/MultiDiskAdaptor.h b/src/MultiDiskAdaptor.h
index 21018259..74713fee 100644
--- a/src/MultiDiskAdaptor.h
+++ b/src/MultiDiskAdaptor.h
@@ -37,6 +37,8 @@
#include "DiskAdaptor.h"
+#include <deque>
+
namespace aria2 {
class MultiFileAllocationIterator;
@@ -112,7 +114,7 @@ public:
typedef SharedHandle<DiskWriterEntry> DiskWriterEntryHandle;
-typedef std::deque<DiskWriterEntryHandle> DiskWriterEntries;
+typedef std::vector<DiskWriterEntryHandle> DiskWriterEntries;
class MultiDiskAdaptor : public DiskAdaptor {
friend class MultiFileAllocationIterator;
@@ -120,7 +122,7 @@ private:
size_t pieceLength;
DiskWriterEntries diskWriterEntries;
- std::deque<SharedHandle<DiskWriterEntry> > _openedDiskWriterEntries;
+ std::vector<SharedHandle<DiskWriterEntry> > _openedDiskWriterEntries;
size_t _maxOpenFiles;
@@ -192,7 +194,7 @@ public:
virtual size_t utime(const Time& actime, const Time& modtime);
- const std::deque<SharedHandle<DiskWriterEntry> >&
+ const std::vector<SharedHandle<DiskWriterEntry> >&
getDiskWriterEntries() const
{
return diskWriterEntries;
diff --git a/src/MultiFileAllocationIterator.cc b/src/MultiFileAllocationIterator.cc
index ff131573..a1f772af 100644
--- a/src/MultiFileAllocationIterator.cc
+++ b/src/MultiFileAllocationIterator.cc
@@ -45,7 +45,8 @@ namespace aria2 {
MultiFileAllocationIterator::MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor):
_diskAdaptor(diskAdaptor),
- _entries(_diskAdaptor->diskWriterEntries),
+ _entries(_diskAdaptor->diskWriterEntries.begin(),
+ _diskAdaptor->diskWriterEntries.end()),
_offset(0)
{}
@@ -111,7 +112,8 @@ uint64_t MultiFileAllocationIterator::getTotalLength()
}
}
-const DiskWriterEntries& MultiFileAllocationIterator::getDiskWriterEntries() const
+const std::deque<SharedHandle<DiskWriterEntry> >&
+MultiFileAllocationIterator::getDiskWriterEntries() const
{
return _entries;
}
diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc
index c0fbb878..11351ad3 100644
--- a/src/MultiUrlRequestInfo.cc
+++ b/src/MultiUrlRequestInfo.cc
@@ -54,6 +54,7 @@
#include "File.h"
#include "Netrc.h"
#include "AuthConfigFactory.h"
+#include "DownloadContext.h"
#ifdef ENABLE_SSL
# include "SocketCore.h"
# include "TLSContext.h"
diff --git a/src/PeerChokeCommand.cc b/src/PeerChokeCommand.cc
index 8799605f..ca1bb1f0 100644
--- a/src/PeerChokeCommand.cc
+++ b/src/PeerChokeCommand.cc
@@ -34,18 +34,15 @@
/* copyright --> */
#include "PeerChokeCommand.h"
#include "DownloadEngine.h"
-#include "BtContext.h"
#include "BtRuntime.h"
#include "PeerStorage.h"
namespace aria2 {
PeerChokeCommand::PeerChokeCommand(int32_t cuid,
- DownloadEngine* e,
- const SharedHandle<BtContext>& btContext):
+ DownloadEngine* e):
Command(cuid),
- e(e),
- _btContext(btContext) {}
+ e(e) {}
PeerChokeCommand::~PeerChokeCommand() {}
diff --git a/src/PeerChokeCommand.h b/src/PeerChokeCommand.h
index b81781f3..7f8baf75 100644
--- a/src/PeerChokeCommand.h
+++ b/src/PeerChokeCommand.h
@@ -41,7 +41,6 @@
namespace aria2 {
class DownloadEngine;
-class BtContext;
class BtRuntime;
class PeerStorage;
@@ -49,15 +48,12 @@ class PeerChokeCommand : public Command {
private:
DownloadEngine* e;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<BtRuntime> _btRuntime;
public:
PeerChokeCommand(int32_t cuid,
- DownloadEngine* e,
- const SharedHandle<BtContext>& btContext);
+ DownloadEngine* e);
virtual ~PeerChokeCommand();
diff --git a/src/PeerInitiateConnectionCommand.cc b/src/PeerInitiateConnectionCommand.cc
index a815bced..bd16a354 100644
--- a/src/PeerInitiateConnectionCommand.cc
+++ b/src/PeerInitiateConnectionCommand.cc
@@ -42,12 +42,12 @@
#include "Socket.h"
#include "Logger.h"
#include "Peer.h"
-#include "BtContext.h"
#include "BtRuntime.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
#include "PeerConnection.h"
#include "RequestGroup.h"
+#include "DownloadContext.h"
namespace aria2 {
@@ -56,13 +56,11 @@ PeerInitiateConnectionCommand::PeerInitiateConnectionCommand
RequestGroup* requestGroup,
const PeerHandle& peer,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SharedHandle<BtRuntime>& btRuntime,
bool mseHandshakeEnabled)
:
PeerAbstractCommand(cuid, peer, e),
_requestGroup(requestGroup),
- _btContext(btContext),
_btRuntime(btRuntime),
_mseHandshakeEnabled(mseHandshakeEnabled)
{
@@ -83,7 +81,7 @@ bool PeerInitiateConnectionCommand::executeInternal() {
socket->establishConnection(peer->ipaddr, peer->port);
if(_mseHandshakeEnabled) {
InitiatorMSEHandshakeCommand* c =
- new InitiatorMSEHandshakeCommand(cuid, _requestGroup, peer, e, _btContext,
+ new InitiatorMSEHandshakeCommand(cuid, _requestGroup, peer, e,
_btRuntime, socket);
c->setPeerStorage(_peerStorage);
c->setPieceStorage(_pieceStorage);
@@ -91,7 +89,7 @@ bool PeerInitiateConnectionCommand::executeInternal() {
} else {
PeerInteractionCommand* command =
new PeerInteractionCommand
- (cuid, _requestGroup, peer, e, _btContext, _btRuntime, _pieceStorage,
+ (cuid, _requestGroup, peer, e, _btRuntime, _pieceStorage,
socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
command->setPeerStorage(_peerStorage);
e->commands.push_back(command);
@@ -106,7 +104,7 @@ bool PeerInitiateConnectionCommand::prepareForNextPeer(time_t wait) {
peer->usedBy(e->newCUID());
PeerInitiateConnectionCommand* command =
new PeerInitiateConnectionCommand(peer->usedBy(), _requestGroup, peer, e,
- _btContext, _btRuntime);
+ _btRuntime);
command->setPeerStorage(_peerStorage);
command->setPieceStorage(_pieceStorage);
e->commands.push_back(command);
diff --git a/src/PeerInitiateConnectionCommand.h b/src/PeerInitiateConnectionCommand.h
index 9ffd5afa..0723eade 100644
--- a/src/PeerInitiateConnectionCommand.h
+++ b/src/PeerInitiateConnectionCommand.h
@@ -40,7 +40,6 @@
namespace aria2 {
class RequestGroup;
-class BtContext;
class BtRuntime;
class PeerStorage;
class PieceStorage;
@@ -49,8 +48,6 @@ class PeerInitiateConnectionCommand : public PeerAbstractCommand {
private:
RequestGroup* _requestGroup;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<PeerStorage> _peerStorage;
@@ -69,7 +66,6 @@ public:
RequestGroup* requestGroup,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SharedHandle<BtRuntime>& btRuntime,
bool mseHandshakeEnabled = true);
diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc
index c3bbc1b9..38644aaf 100644
--- a/src/PeerInteractionCommand.cc
+++ b/src/PeerInteractionCommand.cc
@@ -44,7 +44,7 @@
#include "prefs.h"
#include "Socket.h"
#include "Option.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "BtRegistry.h"
#include "Peer.h"
#include "BtMessage.h"
@@ -70,6 +70,7 @@
#include "DefaultExtensionMessageFactory.h"
#include "RequestGroupMan.h"
#include "ExtensionMessageRegistry.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -78,7 +79,6 @@ PeerInteractionCommand::PeerInteractionCommand
RequestGroup* requestGroup,
const PeerHandle& p,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PieceStorage>& pieceStorage,
const SocketHandle& s,
@@ -86,7 +86,6 @@ PeerInteractionCommand::PeerInteractionCommand
const PeerConnectionHandle& passedPeerConnection)
:PeerAbstractCommand(cuid, p, e, s),
_requestGroup(requestGroup),
- _btContext(btContext),
_btRuntime(btRuntime),
_pieceStorage(pieceStorage),
sequence(sequence)
@@ -98,20 +97,22 @@ PeerInteractionCommand::PeerInteractionCommand
setTimeout(getOption()->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
}
+ const BDE& torrentAttrs =
+ _requestGroup->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<BtRegistry> btRegistry = e->getBtRegistry();
SharedHandle<PeerStorage> peerStorage =
- btRegistry->get(_btContext->getInfoHashAsString())._peerStorage;
+ btRegistry->get(torrentAttrs[bittorrent::INFO_HASH].s())._peerStorage;
SharedHandle<ExtensionMessageRegistry> exMsgRegistry
(new ExtensionMessageRegistry());
SharedHandle<DefaultExtensionMessageFactory> extensionMessageFactory
- (new DefaultExtensionMessageFactory(_btContext, peer, exMsgRegistry));
+ (new DefaultExtensionMessageFactory(peer, exMsgRegistry));
extensionMessageFactory->setPeerStorage(peerStorage);
SharedHandle<DefaultBtMessageFactory> factory(new DefaultBtMessageFactory());
factory->setCuid(cuid);
- factory->setBtContext(_btContext);
+ factory->setDownloadContext(_requestGroup->getDownloadContext());
factory->setPieceStorage(pieceStorage);
factory->setPeerStorage(peerStorage);
factory->setExtensionMessageFactory(extensionMessageFactory);
@@ -132,7 +133,7 @@ PeerInteractionCommand::PeerInteractionCommand
(new DefaultBtMessageDispatcher());
dispatcher->setCuid(cuid);
dispatcher->setPeer(peer);
- dispatcher->setBtContext(_btContext);
+ dispatcher->setDownloadContext(_requestGroup->getDownloadContext());
dispatcher->setPieceStorage(pieceStorage);
dispatcher->setPeerStorage(peerStorage);
dispatcher->setRequestTimeout(getOption()->getAsInt(PREF_BT_REQUEST_TIMEOUT));
@@ -142,7 +143,7 @@ PeerInteractionCommand::PeerInteractionCommand
DefaultBtMessageReceiverHandle receiver(new DefaultBtMessageReceiver());
receiver->setCuid(cuid);
receiver->setPeer(peer);
- receiver->setBtContext(_btContext);
+ receiver->setDownloadContext(_requestGroup->getDownloadContext());
receiver->setPeerConnection(peerConnection);
receiver->setDispatcher(dispatcher);
receiver->setBtMessageFactory(factory);
@@ -151,13 +152,12 @@ PeerInteractionCommand::PeerInteractionCommand
(new DefaultBtRequestFactory());
reqFactory->setCuid(cuid);
reqFactory->setPeer(peer);
- reqFactory->setBtContext(_btContext);
reqFactory->setPieceStorage(pieceStorage);
reqFactory->setBtMessageDispatcher(dispatcher);
reqFactory->setBtMessageFactory(factory);
DefaultBtInteractiveHandle btInteractive
- (new DefaultBtInteractive(_btContext, peer));
+ (new DefaultBtInteractive(_requestGroup->getDownloadContext(), peer));
btInteractive->setBtRuntime(_btRuntime);
btInteractive->setPieceStorage(_pieceStorage);
btInteractive->setPeerStorage(peerStorage); // Note: Not a member variable.
@@ -172,7 +172,7 @@ PeerInteractionCommand::PeerInteractionCommand
(getOption()->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL));
btInteractive->setRequestGroupMan(e->_requestGroupMan);
btInteractive->setBtMessageFactory(factory);
- if(!_btContext->isPrivate()) {
+ if(torrentAttrs[bittorrent::PRIVATE].i() == 0) {
if(getOption()->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
btInteractive->setUTPexEnabled(true);
}
@@ -189,8 +189,9 @@ PeerInteractionCommand::PeerInteractionCommand
factory->setBtRequestFactory(reqFactory);
factory->setPeerConnection(peerConnection);
- peer->allocateSessionResource(_btContext->getPieceLength(),
- _btContext->getTotalLength());
+ peer->allocateSessionResource
+ (_requestGroup->getDownloadContext()->getPieceLength(),
+ _requestGroup->getDownloadContext()->getTotalLength());
peer->setBtMessageDispatcher(dispatcher);
_btRuntime->increaseConnections();
@@ -290,12 +291,8 @@ bool PeerInteractionCommand::prepareForNextPeer(time_t wait) {
PeerHandle peer = _peerStorage->getUnusedPeer();
peer->usedBy(e->newCUID());
PeerInitiateConnectionCommand* command =
- new PeerInitiateConnectionCommand(peer->usedBy(),
- _requestGroup,
- peer,
- e,
- _btContext,
- _btRuntime);
+ new PeerInitiateConnectionCommand
+ (peer->usedBy(), _requestGroup, peer, e, _btRuntime);
command->setPeerStorage(_peerStorage);
command->setPieceStorage(_pieceStorage);
e->commands.push_back(command);
diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h
index a8ed8514..894cda7d 100644
--- a/src/PeerInteractionCommand.h
+++ b/src/PeerInteractionCommand.h
@@ -40,7 +40,6 @@
namespace aria2 {
class RequestGroup;
-class BtContext;
class BtInteractive;
class PeerConnection;
class BtRuntime;
@@ -58,8 +57,6 @@ public:
private:
RequestGroup* _requestGroup;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<PieceStorage> _pieceStorage;
@@ -81,7 +78,6 @@ public:
RequestGroup* requestGroup,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PieceStorage>& pieceStorage,
const SharedHandle<SocketCore>& s,
diff --git a/src/PeerReceiveHandshakeCommand.cc b/src/PeerReceiveHandshakeCommand.cc
index 20df4391..043ec7c2 100644
--- a/src/PeerReceiveHandshakeCommand.cc
+++ b/src/PeerReceiveHandshakeCommand.cc
@@ -37,7 +37,7 @@
#include "DownloadEngine.h"
#include "BtHandshakeMessage.h"
#include "Util.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "DlAbortEx.h"
#include "PeerInteractionCommand.h"
#include "Peer.h"
@@ -91,23 +91,25 @@ bool PeerReceiveHandshakeCommand::executeInternal()
// To handle tracker's NAT-checking feature
if(dataLength >= 48) {
// check info_hash
- std::string infoHash = Util::toHex(&data[28], INFO_HASH_LENGTH);
+ std::string infoHash = std::string(&data[28], &data[28+INFO_HASH_LENGTH]);
BtObject btObject = e->getBtRegistry()->get(infoHash);
- SharedHandle<BtContext> btContext = btObject._btContext;
+ SharedHandle<DownloadContext> downloadContext = btObject._downloadContext;
SharedHandle<BtRuntime> btRuntime = btObject._btRuntime;
SharedHandle<PieceStorage> pieceStorage = btObject._pieceStorage;
SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
- if(btContext.isNull() || !btRuntime->ready()) {
+ if(downloadContext.isNull() || !btRuntime->ready()) {
throw DL_ABORT_EX
- (StringFormat("Unknown info hash %s", infoHash.c_str()).str());
+ (StringFormat("Unknown info hash %s",
+ Util::toHex(infoHash).c_str()).str());
}
- TransferStat tstat = btContext->getOwnerRequestGroup()->calculateStat();
+ TransferStat tstat =
+ downloadContext->getOwnerRequestGroup()->calculateStat();
const unsigned int maxDownloadLimit =
- btContext->getOwnerRequestGroup()->getMaxDownloadSpeedLimit();
+ downloadContext->getOwnerRequestGroup()->getMaxDownloadSpeedLimit();
unsigned int thresholdSpeed =
- btContext->getOwnerRequestGroup()->
+ downloadContext->getOwnerRequestGroup()->
getOption()->getAsInt(PREF_BT_REQUEST_PEER_SPEED_LIMIT);
if(maxDownloadLimit > 0) {
thresholdSpeed = std::min(maxDownloadLimit, thresholdSpeed);
@@ -123,10 +125,9 @@ bool PeerReceiveHandshakeCommand::executeInternal()
PeerInteractionCommand* command =
new PeerInteractionCommand
(cuid,
- btContext->getOwnerRequestGroup(),
+ downloadContext->getOwnerRequestGroup(),
peer,
e,
- btContext,
btRuntime,
pieceStorage,
socket,
diff --git a/src/PieceHashCheckIntegrityEntry.cc b/src/PieceHashCheckIntegrityEntry.cc
index 188e8670..972a40e8 100644
--- a/src/PieceHashCheckIntegrityEntry.cc
+++ b/src/PieceHashCheckIntegrityEntry.cc
@@ -48,8 +48,10 @@ PieceHashCheckIntegrityEntry::~PieceHashCheckIntegrityEntry() {}
bool PieceHashCheckIntegrityEntry::isValidationReady()
{
- DownloadContextHandle dctx = _requestGroup->getDownloadContext();
- return dctx->getPieceHashes().size() > 0 &&
+ const SharedHandle<DownloadContext>& dctx =
+ _requestGroup->getDownloadContext();
+ return !dctx->getPieceHashAlgo().empty() &&
+ dctx->getPieceHashes().size() > 0 &&
dctx->getPieceHashes().size() == dctx->getNumPieces();
}
diff --git a/src/RealtimeCommand.cc b/src/RealtimeCommand.cc
index 0f444ee4..160f1f00 100644
--- a/src/RealtimeCommand.cc
+++ b/src/RealtimeCommand.cc
@@ -36,6 +36,7 @@
#include "DownloadEngine.h"
#include "Exception.h"
#include "RequestGroup.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/ReceiverMSEHandshakeCommand.cc b/src/ReceiverMSEHandshakeCommand.cc
index defe2a22..fa609b60 100644
--- a/src/ReceiverMSEHandshakeCommand.cc
+++ b/src/ReceiverMSEHandshakeCommand.cc
@@ -49,7 +49,7 @@
#include "ARC4Decryptor.h"
#include "RequestGroupMan.h"
#include "BtRegistry.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
#include "BtAnnounce.h"
@@ -135,9 +135,10 @@ bool ReceiverMSEHandshakeCommand::executeInternal()
break;
}
case RECEIVER_RECEIVE_PAD_C_LENGTH: {
- std::deque<SharedHandle<BtContext> > btContexts;
- e->getBtRegistry()->getAllBtContext(std::back_inserter(btContexts));
- if(_mseHandshake->receiveReceiverHashAndPadCLength(btContexts)) {
+ std::deque<SharedHandle<DownloadContext> > downloadContexts;
+ e->getBtRegistry()->getAllDownloadContext
+ (std::back_inserter(downloadContexts));
+ if(_mseHandshake->receiveReceiverHashAndPadCLength(downloadContexts)) {
_sequence = RECEIVER_RECEIVE_PAD_C;
}
break;
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index 0da471b9..2e7d9096 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -48,7 +48,6 @@
#include "File.h"
#include "message.h"
#include "Util.h"
-#include "BtRegistry.h"
#include "LogFactory.h"
#include "Logger.h"
#include "DiskAdaptor.h"
@@ -57,8 +56,7 @@
#include "StreamCheckIntegrityEntry.h"
#include "CheckIntegrityCommand.h"
#include "UnknownLengthPieceStorage.h"
-#include "BtContext.h"
-#include "SingleFileDownloadContext.h"
+#include "DownloadContext.h"
#include "DlAbortEx.h"
#include "DownloadFailureException.h"
#include "RequestGroupMan.h"
@@ -83,6 +81,8 @@
# include "CheckIntegrityCommand.h"
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_BITTORRENT
+# include "bittorrent_helper.h"
+# include "BtRegistry.h"
# include "BtCheckIntegrityEntry.h"
# include "DefaultPeerStorage.h"
# include "DefaultBtAnnounce.h"
@@ -205,39 +205,30 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
{
#ifdef ENABLE_BITTORRENT
{
- BtContextHandle btContext = dynamic_pointer_cast<BtContext>(_downloadContext);
- if(!btContext.isNull()) {
+ if(_downloadContext->hasAttribute(bittorrent::BITTORRENT)) {
+ const BDE& torrentAttrs =
+ _downloadContext->getAttribute(bittorrent::BITTORRENT);
if(_option->getAsBool(PREF_DRY_RUN)) {
throw DOWNLOAD_FAILURE_EXCEPTION
("Cancel BitTorrent download in dry-run context.");
}
SharedHandle<BtRegistry> btRegistry = e->getBtRegistry();
- if(!btRegistry->getBtContext(btContext->getInfoHashAsString()).isNull()) {
+ if(!btRegistry->getDownloadContext
+ (torrentAttrs[bittorrent::INFO_HASH].s()).isNull()) {
throw DOWNLOAD_FAILURE_EXCEPTION
- (StringFormat("InfoHash %s is already registered.",
- btContext->getInfoHashAsString().c_str()).str());
+ (StringFormat
+ ("InfoHash %s is already registered.",
+ Util::toHex(torrentAttrs[bittorrent::INFO_HASH].s()).c_str()).str());
}
if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(EX_DUPLICATE_FILE_DOWNLOAD,
- getFilePath().c_str()).str());
+ _downloadContext->getBasePath().c_str()).str());
}
initPieceStorage();
- if(btContext->getFileEntries().size() > 1) {
- // this is really multi file torrent.
- // clear http/ftp uris because the current implementation does not
- // allow integrating multi-file torrent and http/ftp.
- _logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
- _uris.clear();
-
+ if(_downloadContext->getFileEntries().size() > 1) {
_pieceStorage->setupFileFilter();
- } else if(btContext->getFileEntries().size() == 1) {
- // web-seeding is only enabled for single file torrent
- SharedHandle<FileEntry> fileEntry = btContext->getFileEntries().front();
- _uris.insert(_uris.end(),
- fileEntry->getAssociatedUris().begin(),
- fileEntry->getAssociatedUris().end());
}
SharedHandle<DefaultBtProgressInfoFile>
@@ -252,14 +243,14 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
progressInfoFile->setBtRuntime(btRuntime);
SharedHandle<DefaultPeerStorage> peerStorage
- (new DefaultPeerStorage(btContext, _option.get()));
+ (new DefaultPeerStorage(_option.get()));
peerStorage->setBtRuntime(btRuntime);
peerStorage->setPieceStorage(_pieceStorage);
_peerStorage = peerStorage;
progressInfoFile->setPeerStorage(peerStorage);
SharedHandle<DefaultBtAnnounce> btAnnounce
- (new DefaultBtAnnounce(btContext, _option.get()));
+ (new DefaultBtAnnounce(_downloadContext, _option.get()));
btAnnounce->setBtRuntime(btRuntime);
btAnnounce->setPieceStorage(_pieceStorage);
btAnnounce->setPeerStorage(peerStorage);
@@ -267,8 +258,8 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
(_option->getAsInt(PREF_BT_TRACKER_INTERVAL));
btAnnounce->shuffleAnnounce();
- btRegistry->put(btContext->getInfoHashAsString(),
- BtObject(btContext,
+ btRegistry->put(torrentAttrs[bittorrent::INFO_HASH].s(),
+ BtObject(_downloadContext,
_pieceStorage,
peerStorage,
btAnnounce,
@@ -280,20 +271,20 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
progressInfoFile->removeFile();
_logger->notice(MSG_REMOVED_DEFUNCT_CONTROL_FILE,
progressInfoFile->getFilename().c_str(),
- getFilePath().c_str());
+ _downloadContext->getBasePath().c_str());
}
{
uint64_t actualFileSize = _pieceStorage->getDiskAdaptor()->size();
- if(actualFileSize == btContext->getTotalLength()) {
+ if(actualFileSize == _downloadContext->getTotalLength()) {
// First, make DiskAdaptor read-only mode to allow the
// program to seed file in read-only media.
_pieceStorage->getDiskAdaptor()->enableReadOnly();
} else {
// Open file in writable mode to allow the program
- // truncate the file to btContext->getTotalLength()
+ // truncate the file to _downloadContext->getTotalLength()
_logger->debug("File size not match. File is opened in writable mode."
" Expected:%s Actual:%s",
- Util::uitos(btContext->getTotalLength()).c_str(),
+ Util::uitos(_downloadContext->getTotalLength()).c_str(),
Util::uitos(actualFileSize).c_str());
}
}
@@ -311,7 +302,7 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat
(MSG_FILE_ALREADY_EXISTS,
- getFilePath().c_str()).str());
+ _downloadContext->getBasePath().c_str()).str());
} else {
_pieceStorage->getDiskAdaptor()->openFile();
}
@@ -324,14 +315,22 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
}
_progressInfoFile = progressInfoFile;
- if(!btContext->isPrivate() && _option->getAsBool(PREF_ENABLE_DHT)) {
+ if(torrentAttrs[bittorrent::PRIVATE].i() == 0 &&
+ _option->getAsBool(PREF_ENABLE_DHT)) {
std::deque<Command*> commands;
DHTSetup().setup(commands, e, _option.get());
e->addCommand(commands);
- if(!btContext->getNodes().empty() && DHTSetup::initialized()) {
+ if(!torrentAttrs[bittorrent::NODES].empty() && DHTSetup::initialized()) {
+ std::deque<std::pair<std::string, uint16_t> > entryPoints;
+ const BDE& nodes = torrentAttrs[bittorrent::NODES];
+ for(BDE::List::const_iterator i = nodes.listBegin();
+ i != nodes.listEnd(); ++i) {
+ std::pair<std::string, uint16_t> addr
+ ((*i)[bittorrent::HOSTNAME].s(), (*i)[bittorrent::PORT].i());
+ entryPoints.push_back(addr);
+ }
DHTEntryPointNameResolveCommand* command =
- new DHTEntryPointNameResolveCommand(e->newCUID(), e,
- btContext->getNodes());
+ new DHTEntryPointNameResolveCommand(e->newCUID(), e, entryPoints);
command->setTaskQueue(DHTRegistry::_taskQueue);
command->setTaskFactory(DHTRegistry::_taskFactory);
command->setRoutingTable(DHTRegistry::_routingTable);
@@ -361,8 +360,10 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(EX_DUPLICATE_FILE_DOWNLOAD,
- getFilePath().c_str()).str());
+ _downloadContext->getBasePath().c_str()).str());
}
+ // TODO1.5 Renaming filename doesn't take into account of
+ // multi-file download.
adjustFilename
(SharedHandle<BtProgressInfoFile>(new DefaultBtProgressInfoFile
(_downloadContext,
@@ -375,7 +376,7 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
if(!infoFile->exists() && downloadFinishedByFileLength()) {
_pieceStorage->markAllPiecesDone();
_logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
- _gid, getFilePath().c_str());
+ _gid, _downloadContext->getBasePath().c_str());
} else {
loadAndOpenFile(infoFile);
SharedHandle<CheckIntegrityEntry> checkIntegrityEntry
@@ -412,7 +413,7 @@ void RequestGroup::initPieceStorage()
// downloads. Currently multi-file integrated download is not supported.
if(!_uris.empty() &&
_downloadContext->getFileEntries().size() == 1 &&
- !dynamic_pointer_cast<BtContext>(_downloadContext).isNull()) {
+ _downloadContext->hasAttribute(bittorrent::BITTORRENT)) {
_logger->debug("Using LongestSequencePieceSelector");
ps->setPieceSelector
(SharedHandle<PieceSelector>(new LongestSequencePieceSelector()));
@@ -449,8 +450,7 @@ bool RequestGroup::downloadFinishedByFileLength()
if(!_downloadContext->knowsTotalLength()) {
return false;
}
- // TODO consider the case when the getFilePath() returns dir path.
- File outfile(getFilePath());
+ File outfile(getFirstFilePath());
if(outfile.exists() && _downloadContext->getTotalLength() == outfile.size()) {
return true;
} else {
@@ -468,7 +468,7 @@ void RequestGroup::adjustFilename
} else if(downloadFinishedByFileLength()) {
// File was downloaded already, no need to change file name.
} else {
- File outfile(getFilePath());
+ File outfile(getFirstFilePath());
if(outfile.exists() && _option->getAsBool(PREF_CONTINUE) &&
outfile.size() <= _downloadContext->getTotalLength()) {
// File exists but user decided to resume it.
@@ -498,14 +498,14 @@ void RequestGroup::loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoF
progressInfoFile->removeFile();
_logger->notice(MSG_REMOVED_DEFUNCT_CONTROL_FILE,
progressInfoFile->getFilename().c_str(),
- getFilePath().c_str());
+ _downloadContext->getBasePath().c_str());
}
if(progressInfoFile->exists()) {
progressInfoFile->load();
_pieceStorage->getDiskAdaptor()->openExistingFile();
} else {
- File outfile(getFilePath());
+ File outfile(getFirstFilePath());
if(outfile.exists() && _option->getAsBool(PREF_CONTINUE) &&
outfile.size() <= getTotalLength()) {
_pieceStorage->getDiskAdaptor()->openExistingFile();
@@ -535,43 +535,36 @@ void RequestGroup::shouldCancelDownloadForSafety()
if(_option->getAsBool(PREF_ALLOW_OVERWRITE)) {
return;
}
- File outfile(getFilePath());
+ File outfile(getFirstFilePath());
if(outfile.exists()) {
if(_option->getAsBool(PREF_AUTO_FILE_RENAMING)) {
if(tryAutoFileRenaming()) {
- _logger->notice(MSG_FILE_RENAMED, getFilePath().c_str());
+ _logger->notice(MSG_FILE_RENAMED, getFirstFilePath().c_str());
} else {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat("File renaming failed: %s",
- getFilePath().c_str()).str());
+ getFirstFilePath().c_str()).str());
}
} else {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(MSG_FILE_ALREADY_EXISTS,
- getFilePath().c_str()).str());
+ getFirstFilePath().c_str()).str());
}
}
}
bool RequestGroup::tryAutoFileRenaming()
{
- std::string filepath = getFilePath();
+ std::string filepath = getFirstFilePath();
if(filepath.empty()) {
return false;
}
- SingleFileDownloadContextHandle ctx =
- dynamic_pointer_cast<SingleFileDownloadContext>(_downloadContext);
- // Make a copy of ctx.
- SingleFileDownloadContextHandle tempCtx(new SingleFileDownloadContext(*ctx.get()));
-
- DefaultBtProgressInfoFile tempInfoFile(tempCtx, SharedHandle<PieceStorage>(), 0);
-
for(unsigned int i = 1; i < 10000; ++i) {
File newfile(strconcat(filepath, ".", Util::uitos(i)));
- tempCtx->setUFilename(newfile.getPath());
- tempInfoFile.updateFilename();
- if(!newfile.exists() || (newfile.exists() && tempInfoFile.exists())) {
- ctx->setUFilename(newfile.getPath());
+ // TODO1.5 hard coded ".aria2" extension.
+ File ctrlfile(newfile.getPath()+".aria2");
+ if(!newfile.exists() || (newfile.exists() && ctrlfile.exists())) {
+ _downloadContext->getFirstFileEntry()->setPath(newfile.getPath());
return true;
}
}
@@ -639,8 +632,8 @@ void RequestGroup::createNextCommand(std::deque<Command*>& commands,
static_cast<unsigned int>(_uris.size()));
}
}
-
std::deque<std::string> pendingURIs;
+
for(; numCommand--; ) {
Command* command = new CreateRequestCommand(e->newCUID(), this, e);
_logger->debug("filePath=%s", _downloadContext->getFileEntries().front()->getPath().c_str());
@@ -685,14 +678,14 @@ void RequestGroup::createNextCommand(std::deque<Command*>& commands,
}
}
-std::string RequestGroup::getFilePath() const
+std::string RequestGroup::getFirstFilePath() const
{
assert(!_downloadContext.isNull());
if(inMemoryDownload()) {
static const std::string DIR_MEMORY("[MEMORY]");
- return DIR_MEMORY+File(_downloadContext->getActualBasePath()).getBasename();
+ return DIR_MEMORY+File(_downloadContext->getFirstFileEntry()->getPath()).getBasename();
} else {
- return _downloadContext->getActualBasePath();
+ return _downloadContext->getFirstFileEntry()->getPath();
}
}
@@ -827,24 +820,25 @@ void RequestGroup::setForceHaltRequested(bool f, HaltReason haltReason)
void RequestGroup::releaseRuntimeResource(DownloadEngine* e)
{
#ifdef ENABLE_BITTORRENT
- BtContextHandle btContext = dynamic_pointer_cast<BtContext>(_downloadContext);
- if(!btContext.isNull()) {
+ if(_downloadContext->hasAttribute(bittorrent::BITTORRENT)) {
SharedHandle<BtRegistry> btRegistry = e->getBtRegistry();
- BtContextHandle btContextInReg =
- btRegistry->getBtContext(btContext->getInfoHashAsString());
- // Make sure that the registered BtContext's GID is equal to
- // this->getGID(). Even if createInitialCommand() throws
- // exception without registering this BtContext, after that, this
- // method is called. In this case, just finding BtContext using
- // infoHash may detect another download's BtContext and deleting
- // it from BtRegistry causes Segmentation Fault.
- if(!btContextInReg.isNull() &&
- btContextInReg->getOwnerRequestGroup()->getGID() ==
- btContext->getOwnerRequestGroup()->getGID()) {
- btRegistry->remove(btContext->getInfoHashAsString());
+ const BDE& torrentAttrs =
+ _downloadContext->getAttribute(bittorrent::BITTORRENT);
+ const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s();
+ SharedHandle<DownloadContext> contextInReg =
+ btRegistry->getDownloadContext(infoHash);
+ // Make sure that the registered DownloadContext's GID is equal to
+ // _gid. Even if createInitialCommand() throws exception without
+ // registering this DownloadContext, after that, this method is
+ // called. In this case, just finding DownloadContext using
+ // infoHash may detect another download's DownloadContext and
+ // deleting it from BtRegistry causes Segmentation Fault.
+ if(!contextInReg.isNull() &&
+ contextInReg->getOwnerRequestGroup()->getGID() == _gid) {
+ btRegistry->remove(infoHash);
if(!DHTRegistry::_peerAnnounceStorage.isNull()) {
- DHTRegistry::_peerAnnounceStorage->
- removeLocalPeerAnnounce(btContext->getInfoHash());
+ DHTRegistry::_peerAnnounceStorage->removeLocalPeerAnnounce
+ (torrentAttrs[bittorrent::INFO_HASH].uc());
}
}
}
@@ -856,7 +850,8 @@ void RequestGroup::releaseRuntimeResource(DownloadEngine* e)
void RequestGroup::preDownloadProcessing()
{
- _logger->debug("Finding PreDownloadHandler for path %s.", getFilePath().c_str());
+ _logger->debug("Finding PreDownloadHandler for path %s.",
+ getFirstFilePath().c_str());
try {
for(PreDownloadHandlers::const_iterator itr = _preDownloadHandlers.begin();
itr != _preDownloadHandlers.end(); ++itr) {
@@ -876,7 +871,8 @@ void RequestGroup::preDownloadProcessing()
void RequestGroup::postDownloadProcessing
(std::deque<SharedHandle<RequestGroup> >& groups)
{
- _logger->debug("Finding PostDownloadHandler for path %s.", getFilePath().c_str());
+ _logger->debug("Finding PostDownloadHandler for path %s.",
+ getFirstFilePath().c_str());
try {
for(PostDownloadHandlers::const_iterator itr = _postDownloadHandlers.begin();
itr != _postDownloadHandlers.end(); ++itr) {
@@ -970,11 +966,6 @@ void RequestGroup::clearPreDowloadHandler()
_preDownloadHandlers.clear();
}
-void RequestGroup::setDownloadContext(const DownloadContextHandle& downloadContext)
-{
- _downloadContext = downloadContext;
-}
-
void RequestGroup::setPieceStorage(const PieceStorageHandle& pieceStorage)
{
_pieceStorage = pieceStorage;
@@ -1104,11 +1095,10 @@ void RequestGroup::removeIdenticalURI(const std::string& uri)
void RequestGroup::reportDownloadFinished()
{
_logger->notice(MSG_FILE_DOWNLOAD_COMPLETED,
- getFilePath().c_str());
+ _downloadContext->getBasePath().c_str());
_uriSelector->resetCounters();
#ifdef ENABLE_BITTORRENT
- SharedHandle<BtContext> ctx = dynamic_pointer_cast<BtContext>(_downloadContext);
- if(!ctx.isNull()) {
+ if(_downloadContext->hasAttribute(bittorrent::BITTORRENT)) {
TransferStat stat = calculateStat();
double shareRatio = ((stat.getAllTimeUploadLength()*10)/getCompletedLength())/10.0;
_logger->notice(MSG_SHARE_RATIO_REPORT,
diff --git a/src/RequestGroup.h b/src/RequestGroup.h
index a8c4c388..3d579929 100644
--- a/src/RequestGroup.h
+++ b/src/RequestGroup.h
@@ -221,7 +221,7 @@ public:
void closeFile();
- std::string getFilePath() const;
+ std::string getFirstFilePath() const;
uint64_t getTotalLength() const;
@@ -275,7 +275,10 @@ public:
return _downloadContext;
}
- void setDownloadContext(const SharedHandle<DownloadContext>& downloadContext);
+ void setDownloadContext(const SharedHandle<DownloadContext>& downloadContext)
+ {
+ _downloadContext = downloadContext;
+ }
const SharedHandle<PieceStorage>& getPieceStorage() const
{
diff --git a/src/RequestGroupEntry.cc b/src/RequestGroupEntry.cc
index 01dd9b15..bba57f8b 100644
--- a/src/RequestGroupEntry.cc
+++ b/src/RequestGroupEntry.cc
@@ -35,6 +35,7 @@
#include "RequestGroupEntry.h"
#include "RequestGroup.h"
#include "Command.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc
index 41a0f515..9069a4dd 100644
--- a/src/RequestGroupMan.cc
+++ b/src/RequestGroupMan.cc
@@ -274,7 +274,7 @@ private:
if(!sig.isNull() && !sig->getBody().empty()) {
// filename of signature file is the path to download file followed by
// ".sig".
- std::string signatureFile = group->getFilePath()+".sig";
+ std::string signatureFile = group->getFirstFilePath()+".sig";
if(sig->save(signatureFile)) {
_logger->notice(MSG_SIGNATURE_SAVED, signatureFile.c_str());
} else {
@@ -637,7 +637,7 @@ std::string RequestGroupMan::formatDownloadResult(const std::string& status, con
o << "n/a";
}
o << "|";
- const std::deque<SharedHandle<FileEntry> >& fileEntries =
+ const std::vector<SharedHandle<FileEntry> >& fileEntries =
downloadResult->fileEntries;
if(downloadResult->result == DownloadResult::FINISHED ||
downloadResult->numUri == 0) {
@@ -677,7 +677,7 @@ bool RequestGroupMan::isSameFileBeingDownloaded(RequestGroup* requestGroup) cons
for(RequestGroups::const_iterator itr = _requestGroups.begin();
itr != _requestGroups.end(); ++itr) {
if((*itr).get() != requestGroup) {
- const std::deque<SharedHandle<FileEntry> >& entries =
+ const std::vector<SharedHandle<FileEntry> >& entries =
(*itr)->getDownloadContext()->getFileEntries();
std::transform(entries.begin(), entries.end(),
std::back_inserter(files),
@@ -685,7 +685,7 @@ bool RequestGroupMan::isSameFileBeingDownloaded(RequestGroup* requestGroup) cons
}
}
std::sort(files.begin(), files.end());
- const std::deque<SharedHandle<FileEntry> >& entries =
+ const std::vector<SharedHandle<FileEntry> >& entries =
requestGroup->getDownloadContext()->getFileEntries();
return sameFilePathExists(files.begin(), files.end(),
entries.begin(), entries.end());
diff --git a/src/SeedCheckCommand.cc b/src/SeedCheckCommand.cc
index d005f68e..680f1fdb 100644
--- a/src/SeedCheckCommand.cc
+++ b/src/SeedCheckCommand.cc
@@ -36,23 +36,21 @@
#include "DownloadEngine.h"
#include "BtRuntime.h"
#include "PieceStorage.h"
-#include "BtContext.h"
#include "Logger.h"
#include "SeedCriteria.h"
#include "message.h"
#include "RequestGroup.h"
+#include "DownloadContext.h"
namespace aria2 {
SeedCheckCommand::SeedCheckCommand(int cuid,
RequestGroup* requestGroup,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SeedCriteriaHandle& seedCriteria)
:Command(cuid),
_requestGroup(requestGroup),
e(e),
- _btContext(btContext),
seedCriteria(seedCriteria),
checkStarted(false)
{
diff --git a/src/SeedCheckCommand.h b/src/SeedCheckCommand.h
index 19f6cf5d..7795e68f 100644
--- a/src/SeedCheckCommand.h
+++ b/src/SeedCheckCommand.h
@@ -43,7 +43,6 @@ namespace aria2 {
class RequestGroup;
class DownloadEngine;
class SeedCriteria;
-class BtContext;
class BtRuntime;
class PieceStorage;
@@ -52,7 +51,6 @@ class SeedCheckCommand : public Command
private:
RequestGroup* _requestGroup;
DownloadEngine* e;
- SharedHandle<BtContext> _btContext;
SharedHandle<PieceStorage> _pieceStorage;
SharedHandle<BtRuntime> _btRuntime;
SharedHandle<SeedCriteria> seedCriteria;
@@ -61,7 +59,6 @@ public:
SeedCheckCommand(int cuid,
RequestGroup* requestGroup,
DownloadEngine* e,
- const SharedHandle<BtContext>& btContext,
const SharedHandle<SeedCriteria>& seedCriteria);
virtual ~SeedCheckCommand();
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index 4598e3d3..a3c72a46 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -60,7 +60,7 @@ SegmentEntry::SegmentEntry(cuid_t cuid, const SegmentHandle& segment):
SegmentEntry::~SegmentEntry() {}
SegmentMan::SegmentMan(const Option* option,
- const DownloadContextHandle& downloadContext,
+ const SharedHandle<DownloadContext>& downloadContext,
const PieceStorageHandle& pieceStorage):
_option(option),
logger(LogFactory::getInstance()),
@@ -104,7 +104,8 @@ void SegmentMan::setPieceStorage(const PieceStorageHandle& pieceStorage)
_pieceStorage = pieceStorage;
}
-void SegmentMan::setDownloadContext(const DownloadContextHandle& downloadContext)
+void SegmentMan::setDownloadContext
+(const SharedHandle<DownloadContext>& downloadContext)
{
_downloadContext = downloadContext;
}
diff --git a/src/ShareRatioSeedCriteria.h b/src/ShareRatioSeedCriteria.h
index d09d5219..e4eec635 100644
--- a/src/ShareRatioSeedCriteria.h
+++ b/src/ShareRatioSeedCriteria.h
@@ -36,7 +36,7 @@
#define _D_SHARE_RATIO_SEED_CRITERIA_H_
#include "SeedCriteria.h"
-#include "BtContext.h"
+#include "DownloadContext.h"
#include "PeerStorage.h"
#include "PieceStorage.h"
@@ -45,20 +45,21 @@ namespace aria2 {
class ShareRatioSeedCriteria : public SeedCriteria {
private:
double ratio;
- SharedHandle<BtContext> btContext;
+ SharedHandle<DownloadContext> _downloadContext;
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<PieceStorage> _pieceStorage;
public:
- ShareRatioSeedCriteria(double ratio, const SharedHandle<BtContext>& btContext)
+ ShareRatioSeedCriteria
+ (double ratio, const SharedHandle<DownloadContext>& downloadContext)
:ratio(ratio),
- btContext(btContext) {}
+ _downloadContext(downloadContext) {}
virtual ~ShareRatioSeedCriteria() {}
virtual void reset() {}
virtual bool evaluate() {
- if(btContext->getTotalLength() == 0) {
+ if(_downloadContext->getTotalLength() == 0) {
return false;
}
TransferStat stat = _peerStorage->calculateStat();
diff --git a/src/SingleFileDownloadContext.cc b/src/SingleFileDownloadContext.cc
deleted file mode 100644
index 1acbb2b1..00000000
--- a/src/SingleFileDownloadContext.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/* <!-- 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 "SingleFileDownloadContext.h"
-#include "FileEntry.h"
-
-namespace aria2 {
-
-const std::string SingleFileDownloadContext::DEFAULT_FILENAME("index.html");
-
-SingleFileDownloadContext::SingleFileDownloadContext(size_t pieceLength,
- uint64_t totalLength,
- const std::string& filename,
- const std::string& ufilename):
- _pieceLength(pieceLength),
- _filename(filename),
- _ufilename(ufilename),
- _knowsTotalLength(true)
-{
- _fileEntries.push_back
- (SharedHandle<FileEntry>(new FileEntry(filename, totalLength, 0)));
- updateFileEntry();
-}
-
-void SingleFileDownloadContext::updateFileEntry()
-{
- const SharedHandle<FileEntry>& fileEntry = _fileEntries.front();
- if(!_ufilename.empty()) {
- fileEntry->setPath(_ufilename);
- } else if(!_filename.empty()) {
- fileEntry->setPath(_filename);
- } else {
- fileEntry->setPath("");
- }
-}
-
-const std::deque<std::string>&
-SingleFileDownloadContext::getPieceHashes() const
-{
- return _pieceHashes;
-}
-
-uint64_t SingleFileDownloadContext::getTotalLength() const
-{
- return _fileEntries.front()->getLength();
-}
-
-bool SingleFileDownloadContext::knowsTotalLength() const
-{
- return _knowsTotalLength;
-}
-
-size_t SingleFileDownloadContext::getNumPieces() const
-{
- if(_pieceLength == 0) {
- return 0;
- } else {
- return (_fileEntries.front()->getLength()+_pieceLength-1)/_pieceLength;
- }
-}
-
-std::string SingleFileDownloadContext::getActualBasePath() const
-{
- return _fileEntries.front()->getPath();
-}
-
-void SingleFileDownloadContext::setTotalLength(uint64_t totalLength)
-{
- _fileEntries.front()->setLength(totalLength);
-}
-
-void SingleFileDownloadContext::markTotalLengthIsUnknown()
-{
- _knowsTotalLength = false;
-}
-
-} // namespace aria2
diff --git a/src/SingleFileDownloadContext.h b/src/SingleFileDownloadContext.h
deleted file mode 100644
index 7f07d9a9..00000000
--- a/src/SingleFileDownloadContext.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* <!-- 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_SINGLE_FILE_DOWNLOAD_CONTEXT_H_
-#define _D_SINGLE_FILE_DOWNLOAD_CONTEXT_H_
-
-#include "DownloadContext.h"
-
-#include <string>
-#include <deque>
-
-#include "A2STR.h"
-
-namespace aria2 {
-
-class SingleFileDownloadContext:public DownloadContext
-{
-private:
- size_t _pieceLength;
- /**
- * _filename and _ufilename may contains directory path name. So
- * /usr/local/aria2c is acceptable here. These should be complete
- * file path.
- */
- std::string _filename;
- std::string _ufilename;
-
- std::string _contentType;
-
- std::deque<std::string> _pieceHashes;
- std::string _pieceHashAlgo;
-
- std::string _checksum;
- std::string _checksumHashAlgo;
-
- bool _knowsTotalLength;
-
- void updateFileEntry();
-public:
- SingleFileDownloadContext(size_t pieceLength,
- uint64_t totalLength,
- const std::string& filename,
- const std::string& ufilename = A2STR::NIL);
-
- virtual ~SingleFileDownloadContext() {}
-
- virtual const std::string& getPieceHash(size_t index) const
- {
- if(index < _pieceHashes.size()) {
- return _pieceHashes[index];
- } else {
- return A2STR::NIL;
- }
- }
-
- virtual const std::deque<std::string>& getPieceHashes() const;
-
- virtual uint64_t getTotalLength() const;
-
- virtual bool knowsTotalLength() const;
-
-
- virtual FILE_MODE getFileMode() const
- {
- if(_fileEntries.size() == 1) {
- return SINGLE;
- } else {
- return MULTI;
- }
- }
-
- virtual size_t getPieceLength() const
- {
- return _pieceLength;
- }
-
- virtual size_t getNumPieces() const;
-
- virtual std::string getActualBasePath() const;
-
- virtual const std::string& getPieceHashAlgo() const
- {
- return _pieceHashAlgo;
- }
-
- const std::string& getChecksumHashAlgo() const
- {
- return _checksumHashAlgo;
- }
-
- const std::string& getChecksum() const
- {
- return _checksum;
- }
-
- void setPieceHashes(const std::deque<std::string>& pieceHashes)
- {
- _pieceHashes = pieceHashes;
- }
-
- void setChecksumHashAlgo(const std::string& algo)
- {
- _checksumHashAlgo = algo;
- }
-
- void setChecksum(const std::string& checksum)
- {
- _checksum = checksum;
- }
-
- void setFilename(const std::string& filename)
- {
- _filename = filename;
- updateFileEntry();
- }
-
- void setUFilename(const std::string& ufilename)
- {
- _ufilename = ufilename;
- updateFileEntry();
- }
-
- void setTotalLength(uint64_t totalLength);
-
- void markTotalLengthIsUnknown();
-
- void setPieceHashAlgo(const std::string& algo)
- {
- _pieceHashAlgo = algo;
- }
-
- void setContentType(const std::string& contentType)
- {
- _contentType = contentType;
- }
-
- const std::string& getContentType()
- {
- return _contentType;
- }
-
- static const std::string DEFAULT_FILENAME;
-};
-
-typedef SharedHandle<SingleFileDownloadContext> SingleFileDownloadContextHandle;
-
-} // namespace aria2
-
-#endif // _D_SINGLE_FILE_DOWNLOAD_CONTEXT_H_
diff --git a/src/SleepCommand.cc b/src/SleepCommand.cc
index 17912215..5fd18604 100644
--- a/src/SleepCommand.cc
+++ b/src/SleepCommand.cc
@@ -35,6 +35,7 @@
#include "SleepCommand.h"
#include "RequestGroup.h"
#include "DownloadEngine.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/StreamCheckIntegrityEntry.cc b/src/StreamCheckIntegrityEntry.cc
index 5a4014c3..39e25393 100644
--- a/src/StreamCheckIntegrityEntry.cc
+++ b/src/StreamCheckIntegrityEntry.cc
@@ -37,6 +37,7 @@
#include "DownloadEngine.h"
#include "StreamFileAllocationEntry.h"
#include "Request.h"
+#include "DownloadContext.h"
namespace aria2 {
diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc
index 87a51c58..dddf163e 100644
--- a/src/TrackerWatcherCommand.cc
+++ b/src/TrackerWatcherCommand.cc
@@ -37,7 +37,6 @@
#include <sstream>
#include "DownloadEngine.h"
-#include "BtContext.h"
#include "BtAnnounce.h"
#include "BtRuntime.h"
#include "PieceStorage.h"
@@ -45,7 +44,6 @@
#include "Peer.h"
#include "prefs.h"
#include "message.h"
-#include "SingleFileDownloadContext.h"
#include "ByteArrayDiskWriterFactory.h"
#include "RecoverableException.h"
#include "PeerInitiateConnectionCommand.h"
@@ -59,17 +57,16 @@
#include "SocketCore.h"
#include "Request.h"
#include "AnnounceTier.h"
+#include "DownloadContext.h"
+#include "bittorrent_helper.h"
namespace aria2 {
-TrackerWatcherCommand::TrackerWatcherCommand(int32_t cuid,
- RequestGroup* requestGroup,
- DownloadEngine* e,
- const BtContextHandle& btContext):
+TrackerWatcherCommand::TrackerWatcherCommand
+(int32_t cuid, RequestGroup* requestGroup, DownloadEngine* e):
Command(cuid),
_requestGroup(requestGroup),
- e(e),
- _btContext(btContext)
+ e(e)
{
_requestGroup->increaseNumCommand();
}
@@ -162,12 +159,8 @@ void TrackerWatcherCommand::processTrackerResponse
}
peer->usedBy(e->newCUID());
PeerInitiateConnectionCommand* command =
- new PeerInitiateConnectionCommand(peer->usedBy(),
- _requestGroup,
- peer,
- e,
- _btContext,
- _btRuntime);
+ new PeerInitiateConnectionCommand
+ (peer->usedBy(), _requestGroup, peer, e, _btRuntime);
command->setPeerStorage(_peerStorage);
command->setPieceStorage(_pieceStorage);
e->commands.push_back(command);
@@ -185,15 +178,17 @@ RequestGroupHandle TrackerWatcherCommand::createAnnounce() {
}
static bool backupTrackerIsAvailable
-(const std::deque<SharedHandle<AnnounceTier> >& announceTiers)
+(const SharedHandle<DownloadContext>& context)
{
- if(announceTiers.size() >= 2) {
+ const BDE& announceList =
+ context->getAttribute(bittorrent::BITTORRENT)[bittorrent::ANNOUNCE_LIST];
+ if(announceList.size() >= 2) {
return true;
}
- if(announceTiers.empty()) {
+ if(announceList.empty()) {
return false;
}
- if(announceTiers[0]->urls.size() >= 2) {
+ if(announceList[0].size() >= 2) {
return true;
} else {
return false;
@@ -208,7 +203,7 @@ TrackerWatcherCommand::createRequestGroup(const std::string& uri)
RequestGroupHandle rg(new RequestGroup(getOption(), uris));
// If backup tracker is available, only try 2 times for each tracker
// and if they all fails, then try next one.
- if(backupTrackerIsAvailable(_btContext->getAnnounceTiers())) {
+ if(backupTrackerIsAvailable(_requestGroup->getDownloadContext())) {
logger->debug("This is multi-tracker announce.");
rg->getOption()->put(PREF_MAX_TRIES, "2");
} else {
@@ -217,11 +212,10 @@ TrackerWatcherCommand::createRequestGroup(const std::string& uri)
}
static const std::string TRACKER_ANNOUNCE_FILE("[tracker.announce]");
- SingleFileDownloadContextHandle dctx
- (new SingleFileDownloadContext(getOption()->getAsInt(PREF_SEGMENT_SIZE),
- 0,
- A2STR::NIL,
- TRACKER_ANNOUNCE_FILE));
+ SharedHandle<DownloadContext> dctx
+ (new DownloadContext(getOption()->getAsInt(PREF_SEGMENT_SIZE),
+ 0,
+ TRACKER_ANNOUNCE_FILE));
dctx->setDir(A2STR::NIL);
dctx->getFileEntries().front()->setUris(uris);
rg->setDownloadContext(dctx);
diff --git a/src/TrackerWatcherCommand.h b/src/TrackerWatcherCommand.h
index 9c7c2417..7ec0c03f 100644
--- a/src/TrackerWatcherCommand.h
+++ b/src/TrackerWatcherCommand.h
@@ -42,7 +42,6 @@ namespace aria2 {
class DownloadEngine;
class RequestGroup;
-class BtContext;
class PeerStorage;
class PieceStorage;
class BtRuntime;
@@ -56,8 +55,6 @@ private:
DownloadEngine* e;
- SharedHandle<BtContext> _btContext;
-
SharedHandle<PeerStorage> _peerStorage;
SharedHandle<PieceStorage> _pieceStorage;
@@ -81,8 +78,7 @@ private:
public:
TrackerWatcherCommand(int32_t cuid,
RequestGroup* requestGroup,
- DownloadEngine* e,
- const SharedHandle<BtContext>& btContext);
+ DownloadEngine* e);
virtual ~TrackerWatcherCommand();
diff --git a/src/UnknownLengthPieceStorage.cc b/src/UnknownLengthPieceStorage.cc
index 369767c7..878fff93 100644
--- a/src/UnknownLengthPieceStorage.cc
+++ b/src/UnknownLengthPieceStorage.cc
@@ -46,8 +46,9 @@
namespace aria2 {
-UnknownLengthPieceStorage::UnknownLengthPieceStorage(const DownloadContextHandle& downloadContext,
- const Option* option):
+UnknownLengthPieceStorage::UnknownLengthPieceStorage
+(const SharedHandle<DownloadContext>& downloadContext,
+ const Option* option):
_downloadContext(downloadContext),
_option(option),
_diskWriterFactory(new DefaultDiskWriterFactory()),
@@ -60,7 +61,8 @@ void UnknownLengthPieceStorage::initStorage()
{
DirectDiskAdaptorHandle directDiskAdaptor(new DirectDiskAdaptor());
directDiskAdaptor->setTotalLength(_downloadContext->getTotalLength());
- directDiskAdaptor->setFileEntries(_downloadContext->getFileEntries());
+ directDiskAdaptor->setFileEntries(_downloadContext->getFileEntries().begin(),
+ _downloadContext->getFileEntries().end());
DiskWriterHandle writer =
_diskWriterFactory->newDiskWriter(directDiskAdaptor->getFilePath());
diff --git a/src/Util.cc b/src/Util.cc
index c2cabda1..0ade0084 100644
--- a/src/Util.cc
+++ b/src/Util.cc
@@ -43,7 +43,6 @@
#include <cstring>
#include <cstdio>
#include <cstdlib>
-#include <iomanip>
#include <sstream>
#include <ostream>
#include <algorithm>
@@ -709,20 +708,6 @@ time_t Util::httpGMT(const std::string& httpStdTime)
return thetime;
}
-void Util::toStream(std::ostream& os, const FileEntries& fileEntries)
-{
- os << _("Files:") << "\n";
- os << "idx|path/length" << "\n";
- os << "===+===========================================================================" << "\n";
- int32_t count = 1;
- for(FileEntries::const_iterator itr = fileEntries.begin();
- itr != fileEntries.end(); ++count, ++itr) {
- os << std::setw(3) << count << "|" << (*itr)->getPath() << "\n";
- os << " |" << Util::abbrevSize((*itr)->getLength()) << "B" << "\n";
- os << "---+---------------------------------------------------------------------------" << "\n";
- }
-}
-
void Util::sleep(long seconds) {
#ifdef HAVE_SLEEP
::sleep(seconds);
diff --git a/src/Util.h b/src/Util.h
index fd5da150..6a54de02 100644
--- a/src/Util.h
+++ b/src/Util.h
@@ -43,8 +43,10 @@
#include <utility>
#include <deque>
#include <iosfwd>
+#include <ostream>
#include <numeric>
#include <map>
+#include <iomanip>
#include "SharedHandle.h"
#include "IntSequence.h"
@@ -243,8 +245,20 @@ public:
*/
static time_t httpGMT(const std::string& httpTimeFormat);
- static void toStream(std::ostream& os,
- const std::deque<SharedHandle<FileEntry> >& entries);
+ template<typename InputIterator>
+ static void toStream
+ (InputIterator first, InputIterator last, std::ostream& os)
+ {
+ os << _("Files:") << "\n";
+ os << "idx|path/length" << "\n";
+ os << "===+===========================================================================" << "\n";
+ int32_t count = 1;
+ for(; first != last; ++first, ++count) {
+ os << std::setw(3) << count << "|" << (*first)->getPath() << "\n";
+ os << " |" << Util::abbrevSize((*first)->getLength()) << "B" << "\n";
+ os << "---+---------------------------------------------------------------------------" << "\n";
+ }
+ }
static void sleep(long seconds);
diff --git a/src/XmlRpcMethodImpl.cc b/src/XmlRpcMethodImpl.cc
index 8bc629a2..954369c2 100644
--- a/src/XmlRpcMethodImpl.cc
+++ b/src/XmlRpcMethodImpl.cc
@@ -51,17 +51,20 @@
#include "StringFormat.h"
#include "XmlRpcRequest.h"
#include "PieceStorage.h"
-#include "PeerStorage.h"
-#include "BtContext.h"
-#include "BtRegistry.h"
-#include "Peer.h"
+#include "DownloadContext.h"
#include "DiskAdaptor.h"
#include "FileEntry.h"
#include "BtProgressInfoFile.h"
-#include "BtRuntime.h"
-#include "BtAnnounce.h"
#include "prefs.h"
#include "message.h"
+#ifdef ENABLE_BITTORRENT
+# include "bittorrent_helper.h"
+# include "BtRegistry.h"
+# include "PeerStorage.h"
+# include "Peer.h"
+# include "BtRuntime.h"
+# include "BtAnnounce.h"
+#endif // ENABLE_BITTORRENT
namespace aria2 {
@@ -286,13 +289,12 @@ static void gatherProgressCommon
#ifdef ENABLE_BITTORRENT
static void gatherProgressBitTorrent
-(BDE& entryDict, const SharedHandle<BtContext>& btctx,
- const SharedHandle<BtRegistry>& btreg)
+(BDE& entryDict, const BDE& torrentAttrs, const SharedHandle<BtRegistry>& btreg)
{
- entryDict["infoHash"] = btctx->getInfoHashAsString();
+ const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s();
+ entryDict["infoHash"] = Util::toHex(infoHash);
- SharedHandle<PeerStorage> peerStorage =
- btreg->get(btctx->getInfoHashAsString())._peerStorage;
+ SharedHandle<PeerStorage> peerStorage = btreg->get(infoHash)._peerStorage;
assert(!peerStorage.isNull());
std::deque<SharedHandle<Peer> > peers;
@@ -329,11 +331,11 @@ static void gatherProgress
{
gatherProgressCommon(entryDict, group);
#ifdef ENABLE_BITTORRENT
- SharedHandle<BtContext> btctx =
- dynamic_pointer_cast<BtContext>(group->getDownloadContext());
- if(!btctx.isNull()) {
+ if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
+ const BDE& torrentAttrs =
+ group->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<BtRegistry> btreg = e->getBtRegistry();
- gatherProgressBitTorrent(entryDict, btctx, btreg);
+ gatherProgressBitTorrent(entryDict, torrentAttrs, btreg);
}
#endif // ENABLE_BITTORRENT
}
@@ -400,9 +402,9 @@ BDE GetFilesXmlRpcMethod::process
createFileEntry(files, dr->fileEntries.begin(), dr->fileEntries.end());
}
} else {
- const std::deque<SharedHandle<FileEntry> >& fileEntries =
- group->getDownloadContext()->getFileEntries();
- createFileEntry(files, fileEntries.begin(), fileEntries.end());
+ createFileEntry(files,
+ group->getDownloadContext()->getFileEntries().begin(),
+ group->getDownloadContext()->getFileEntries().end());
}
return files;
}
@@ -455,12 +457,12 @@ BDE GetPeersXmlRpcMethod::process
(StringFormat("No peer data is available for GID#%d", gid).str());
}
BDE peers = BDE::list();
- SharedHandle<BtContext> btctx =
- dynamic_pointer_cast<BtContext>(group->getDownloadContext());
- if(!btctx.isNull()) {
+ if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
SharedHandle<BtRegistry> btreg = e->getBtRegistry();
+ const BDE& torrentAttrs =
+ group->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<PeerStorage> peerStorage =
- btreg->get(btctx->getInfoHashAsString())._peerStorage;
+ btreg->get(torrentAttrs[bittorrent::INFO_HASH].s())._peerStorage;
assert(!peerStorage.isNull());
BDE entry = BDE::dict();
gatherPeer(peers, peerStorage);
diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc
new file mode 100644
index 00000000..cb3be528
--- /dev/null
+++ b/src/bittorrent_helper.cc
@@ -0,0 +1,529 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2009 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 "bittorrent_helper.h"
+
+#include <algorithm>
+#include <deque>
+
+#include "DownloadContext.h"
+#include "Randomizer.h"
+#include "bencode.h"
+#include "Util.h"
+#include "DlAbortEx.h"
+#include "message.h"
+#include "StringFormat.h"
+#include "BtConstants.h"
+#include "messageDigest.h"
+#include "MessageDigestHelper.h"
+#include "PeerMessageUtil.h"
+#include "SimpleRandomizer.h"
+
+namespace aria2 {
+
+namespace bittorrent {
+
+static const std::string C_NAME("name");
+
+static const std::string C_NAME_UTF8("name.utf-8");
+
+static const std::string C_FILES("files");
+
+static const std::string C_LENGTH("length");
+
+static const std::string C_PATH("path");
+
+static const std::string C_PATH_UTF8("path.utf-8");
+
+static const std::string C_INFO("info");
+
+static const std::string C_PIECES("pieces");
+
+static const std::string C_PIECE_LENGTH("piece length");
+
+static const std::string C_PRIVATE("private");
+
+static const std::string C_URL_LIST("url-list");
+
+static const std::string C_ANNOUNCE("announce");
+
+static const std::string C_ANNOUNCE_LIST("announce-list");
+
+static const std::string C_NODES("nodes");
+
+static const std::string DEFAULT_PEER_ID_PREFIX("-aria2-");
+
+const std::string INFO_HASH("infoHash");
+
+const std::string MODE("mode");
+
+const std::string PRIVATE("private");
+
+const std::string ANNOUNCE_LIST("announceList");
+
+const std::string NODES("nodes");
+
+const std::string HOSTNAME("hostname");
+
+const std::string PORT("port");
+
+const std::string NAME("name");
+
+const std::string BITTORRENT("bittorrent");
+
+const std::string MULTI("multi");
+
+const std::string SINGLE("single");
+
+static void extractPieceHash(const SharedHandle<DownloadContext>& ctx,
+ const std::string& hashData,
+ size_t hashLength,
+ size_t numPieces)
+{
+ std::vector<std::string> pieceHashes;
+ for(size_t i = 0; i < numPieces; ++i) {
+ pieceHashes.push_back(Util::toHex(hashData.data()+i*hashLength,
+ hashLength));
+ }
+ ctx->setPieceHashes(pieceHashes.begin(), pieceHashes.end());
+ ctx->setPieceHashAlgo(MessageDigestContext::SHA1);
+}
+
+static void extractUrlList(std::vector<std::string>& uris, const BDE& bde)
+{
+ if(bde.isList()) {
+ for(BDE::List::const_iterator itr = bde.listBegin();
+ itr != bde.listEnd(); ++itr) {
+ if((*itr).isString()) {
+ uris.push_back((*itr).s());
+ }
+ }
+ } else if(bde.isString()) {
+ uris.push_back(bde.s());
+ }
+}
+
+static void extractFileEntries
+(const SharedHandle<DownloadContext>& ctx,
+ BDE& torrent,
+ const BDE& infoDict,
+ const std::string& defaultName,
+ const std::string& overrideName,
+ const std::vector<std::string>& urlList)
+{
+ std::string name;
+ if(overrideName.empty()) {
+ std::string nameKey;
+ if(infoDict.containsKey(C_NAME_UTF8)) {
+ nameKey = C_NAME_UTF8;
+ } else {
+ nameKey = C_NAME;
+ }
+ const BDE& nameData = infoDict[nameKey];
+ if(nameData.isString()) {
+ // Slice path by '/' just in case nasty ".." is included in name
+ std::deque<std::string> pathelems;
+ Util::slice(pathelems, nameData.s(), '/');
+ name = Util::joinPath(pathelems.begin(), pathelems.end());
+ torrent[NAME] = nameData.s();
+ } else {
+ name = strconcat(File(defaultName).getBasename(), ".file");
+ torrent[NAME] = name;
+ }
+ } else {
+ name = overrideName;
+ torrent[NAME] = name;
+ }
+
+ const BDE& filesList = infoDict[C_FILES];
+ std::vector<SharedHandle<FileEntry> > fileEntries;
+ if(filesList.isList()) {
+ uint64_t length = 0;
+ off_t offset = 0;
+ // multi-file mode
+ torrent[MODE] = MULTI;
+ for(BDE::List::const_iterator itr = filesList.listBegin();
+ itr != filesList.listEnd(); ++itr) {
+ const BDE& fileDict = *itr;
+ if(!fileDict.isDict()) {
+ continue;
+ }
+ const BDE& fileLengthData = fileDict[C_LENGTH];
+ if(!fileLengthData.isInteger()) {
+ throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
+ C_LENGTH.c_str()).str());
+ }
+ length += fileLengthData.i();
+
+ std::string pathKey;
+ if(fileDict.containsKey(C_PATH_UTF8)) {
+ pathKey = C_PATH_UTF8;
+ } else {
+ pathKey = C_PATH;
+ }
+ const BDE& pathList = fileDict[pathKey];
+ if(!pathList.isList() || pathList.empty()) {
+ throw DL_ABORT_EX("Path is empty.");
+ }
+
+ std::vector<std::string> pathelem(pathList.size());
+ std::transform(pathList.listBegin(), pathList.listEnd(), pathelem.begin(),
+ std::mem_fun_ref(&BDE::s));
+ std::string path = name;
+ strappend(path, "/", Util::joinPath(pathelem.begin(), pathelem.end()));
+ // Split path with '/' again because each pathList element can
+ // contain "/" inside.
+ std::deque<std::string> elements;
+ Util::slice(elements, path, '/');
+ path = Util::joinPath(elements.begin(), elements.end());
+
+ std::deque<std::string> uris;
+ std::transform(urlList.begin(), urlList.end(), std::back_inserter(uris),
+ std::bind2nd(std::plus<std::string>(), "/"+path));
+ SharedHandle<FileEntry> fileEntry
+ (new FileEntry(strconcat(ctx->getDir(), "/", path),
+ fileLengthData.i(),
+ offset, uris));
+ fileEntries.push_back(fileEntry);
+ offset += fileEntry->getLength();
+ }
+ } else {
+ // single-file mode;
+ torrent[MODE] = SINGLE;
+ const BDE& lengthData = infoDict[C_LENGTH];
+ if(!lengthData.isInteger()) {
+ throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
+ C_LENGTH.c_str()).str());
+ }
+ uint64_t totalLength = lengthData.i();
+
+ // For each uri in urlList, if it ends with '/', then
+ // concatenate name to it. Specification just says so.
+ std::deque<std::string> uris;
+ for(std::vector<std::string>::const_iterator i = urlList.begin();
+ i != urlList.end(); ++i) {
+ if(Util::endsWith(*i, "/")) {
+ uris.push_back((*i)+name);
+ } else {
+ uris.push_back(*i);
+ }
+ }
+
+ SharedHandle<FileEntry> fileEntry
+ (new FileEntry(strconcat(ctx->getDir(), "/", name),totalLength, 0,
+ uris));
+ fileEntries.push_back(fileEntry);
+ }
+ ctx->setFileEntries(fileEntries.begin(), fileEntries.end());
+ if(torrent[MODE].s() == MULTI) {
+ ctx->setBasePath(strconcat(ctx->getDir(), "/", name));
+ }
+}
+
+static void extractAnnounce(BDE& torrent, const BDE& rootDict)
+{
+ const BDE& announceList = rootDict[C_ANNOUNCE_LIST];
+ if(announceList.isList()) {
+ torrent[ANNOUNCE_LIST] = announceList;
+ } else {
+ const BDE& announce = rootDict[C_ANNOUNCE];
+ BDE announceList = BDE::list();
+ if(announce.isString()) {
+ announceList << BDE::list();
+ announceList[0] << announce;
+ }
+ torrent[ANNOUNCE_LIST] = announceList;
+ }
+}
+
+static void extractNodes(BDE& torrent, const BDE& nodesList)
+{
+ BDE nodes = BDE::list();
+ if(nodesList.isList()) {
+ for(BDE::List::const_iterator i = nodesList.listBegin();
+ i != nodesList.listEnd(); ++i) {
+ const BDE& addrPairList = (*i);
+ if(!addrPairList.isList() || addrPairList.size() != 2) {
+ continue;
+ }
+ const BDE& hostname = addrPairList[0];
+ if(!hostname.isString()) {
+ continue;
+ }
+ if(Util::trim(hostname.s()).empty()) {
+ continue;
+ }
+ const BDE& port = addrPairList[1];
+ if(!port.isInteger() || !(0 < port.i() && port.i() < 65536)) {
+ continue;
+ }
+ BDE node = BDE::dict();
+ node[HOSTNAME] = hostname;
+ node[PORT] = port;
+ nodes << node;
+ }
+ }
+ torrent[NODES] = nodes;
+}
+
+static void processRootDictionary
+(const SharedHandle<DownloadContext>& ctx,
+ const BDE& rootDict,
+ const std::string& defaultName,
+ const std::string& overrideName)
+{
+ if(!rootDict.isDict()) {
+ throw DL_ABORT_EX("torrent file does not contain a root dictionary.");
+ }
+ const BDE& infoDict = rootDict[C_INFO];
+ if(!infoDict.isDict()) {
+ throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
+ C_INFO.c_str()).str());
+ }
+ BDE torrent = BDE::dict();
+
+ // retrieve infoHash
+ std::string encodedInfoDict = bencode::encode(infoDict);
+ unsigned char infoHash[INFO_HASH_LENGTH];
+ MessageDigestHelper::digest(infoHash, INFO_HASH_LENGTH,
+ MessageDigestContext::SHA1,
+ encodedInfoDict.data(),
+ encodedInfoDict.size());
+ torrent[INFO_HASH] = std::string(&infoHash[0], &infoHash[INFO_HASH_LENGTH]);
+
+ // calculate the number of pieces
+ const BDE& piecesData = infoDict[C_PIECES];
+ if(!piecesData.isString()) {
+ throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
+ C_PIECES.c_str()).str());
+ }
+ if(piecesData.s().empty()) {
+ throw DL_ABORT_EX("The length of piece hash is 0.");
+ }
+ size_t numPieces = piecesData.s().size()/PIECE_HASH_LENGTH;
+ if(numPieces == 0) {
+ throw DL_ABORT_EX("The number of pieces is 0.");
+ }
+ // retrieve piece length
+ const BDE& pieceLengthData = infoDict[C_PIECE_LENGTH];
+ if(!pieceLengthData.isInteger()) {
+ throw DL_ABORT_EX(StringFormat(MSG_MISSING_BT_INFO,
+ C_PIECE_LENGTH.c_str()).str());
+ }
+ size_t pieceLength = pieceLengthData.i();
+ ctx->setPieceLength(pieceLength);
+ // retrieve piece hashes
+ extractPieceHash(ctx, piecesData.s(), PIECE_HASH_LENGTH, numPieces);
+ // private flag
+ const BDE& privateData = infoDict[C_PRIVATE];
+ int privatefg = 0;
+ if(privateData.isInteger()) {
+ if(privateData.i() == 1) {
+ privatefg = 1;
+ }
+ }
+ torrent[PRIVATE] = BDE((int64_t)privatefg);
+ // retrieve uri-list.
+ // This implemantation obeys HTTP-Seeding specification:
+ // see http://www.getright.com/seedtorrent.html
+ std::vector<std::string> urlList;
+ extractUrlList(urlList, rootDict[C_URL_LIST]);
+
+ // retrieve file entries
+ extractFileEntries(ctx, torrent, infoDict, defaultName, overrideName, urlList);
+ if((ctx->getTotalLength()+pieceLength-1)/pieceLength != numPieces) {
+ throw DL_ABORT_EX("Too few/many piece hash.");
+ }
+ // retrieve announce
+ extractAnnounce(torrent, rootDict);
+ // retrieve nodes
+ extractNodes(torrent, rootDict[C_NODES]);
+
+ ctx->setAttribute(BITTORRENT, torrent);
+}
+
+void load(const std::string& torrentFile,
+ const SharedHandle<DownloadContext>& ctx,
+ const std::string& overrideName)
+{
+ processRootDictionary(ctx,
+ bencode::decodeFromFile(torrentFile),
+ torrentFile,
+ overrideName);
+
+}
+
+void loadFromMemory(const unsigned char* content,
+ size_t length,
+ const SharedHandle<DownloadContext>& ctx,
+ const std::string& defaultName,
+ const std::string& overrideName)
+{
+ processRootDictionary(ctx,
+ bencode::decode(content, length),
+ defaultName,
+ overrideName);
+}
+
+void loadFromMemory(const std::string& context,
+ const SharedHandle<DownloadContext>& ctx,
+ const std::string& defaultName,
+ const std::string& overrideName)
+{
+ processRootDictionary
+ (ctx,
+ bencode::decode(reinterpret_cast<const unsigned char*>(context.c_str()),
+ context.size()),
+ defaultName, overrideName);
+}
+
+const unsigned char*
+getInfoHash(const SharedHandle<DownloadContext>& downloadContext)
+{
+ return downloadContext->getAttribute(BITTORRENT)[INFO_HASH].uc();
+}
+
+std::string
+getInfoHashString(const SharedHandle<DownloadContext>& downloadContext)
+{
+ return Util::toHex(downloadContext->getAttribute(BITTORRENT)[INFO_HASH].s());
+}
+
+void print(std::ostream& o, const SharedHandle<DownloadContext>& dctx)
+{
+ const BDE& torrentAttrs = dctx->getAttribute(BITTORRENT);
+ o << "*** BitTorrent File Information ***" << "\n";
+ o << "Mode: " << torrentAttrs[MODE].s() << "\n";
+ o << "Announce:" << "\n";
+ const BDE& announceList = torrentAttrs[ANNOUNCE_LIST];
+ for(BDE::List::const_iterator tieritr = announceList.listBegin();
+ tieritr != announceList.listEnd(); ++tieritr) {
+ if(!(*tieritr).isList()) {
+ continue;
+ }
+ for(BDE::List::const_iterator i = (*tieritr).listBegin();
+ i != (*tieritr).listEnd(); ++i) {
+ o << " " << (*i).s();
+ }
+ o << "\n";
+ }
+ o << "Info Hash: " << Util::toHex(torrentAttrs[INFO_HASH].s()) << "\n";
+ o << "Piece Length: " << Util::abbrevSize(dctx->getPieceLength()) << "B\n";
+ o << "The Number of Pieces: " << dctx->getNumPieces() << "\n";
+ o << "Total Length: " << Util::abbrevSize(dctx->getTotalLength()) << "B\n";
+ o << "Name: " << torrentAttrs[NAME].s() << "\n";
+ Util::toStream(dctx->getFileEntries().begin(), dctx->getFileEntries().end(), o);
+}
+
+void computeFastSet
+(std::vector<size_t>& fastSet, const std::string& ipaddr,
+ size_t numPieces, const unsigned char* infoHash, size_t fastSetSize)
+{
+ unsigned char compact[6];
+ if(!PeerMessageUtil::createcompact(compact, ipaddr, 0)) {
+ return;
+ }
+ if(numPieces < fastSetSize) {
+ fastSetSize = numPieces;
+ }
+ unsigned char tx[24];
+ memcpy(tx, compact, 4);
+ if((tx[0] & 0x80) == 0 || (tx[0] & 0x40) == 0) {
+ tx[2] = 0x00;
+ tx[3] = 0x00;
+ } else {
+ tx[3] = 0x00;
+ }
+ memcpy(tx+4, infoHash, 20);
+ unsigned char x[20];
+ MessageDigestHelper::digest(x, sizeof(x), MessageDigestContext::SHA1, tx, 24);
+ while(fastSet.size() < fastSetSize) {
+ for(size_t i = 0; i < 5 && fastSet.size() < fastSetSize; ++i) {
+ size_t j = i*4;
+ uint32_t ny;
+ memcpy(&ny, x+j, 4);
+ uint32_t y = ntohl(ny);
+ size_t index = y%numPieces;
+ if(std::find(fastSet.begin(), fastSet.end(), index) == fastSet.end()) {
+ fastSet.push_back(index);
+ }
+ }
+ unsigned char temp[20];
+ MessageDigestHelper::digest(temp, sizeof(temp), MessageDigestContext::SHA1, x, sizeof(x));
+ memcpy(x, temp, sizeof(x));
+ }
+}
+
+std::string generatePeerId
+(const std::string& peerIdPrefix, const SharedHandle<Randomizer>& randomizer)
+{
+ std::string peerId = peerIdPrefix;
+ peerId += Util::randomAlpha(20-peerIdPrefix.size(), randomizer);
+ if(peerId.size() > 20) {
+ peerId.erase(20);
+ }
+ return peerId;
+}
+
+static std::string peerId;
+
+const std::string& generateStaticPeerId
+(const std::string& peerIdPrefix, const SharedHandle<Randomizer>& randomizer)
+{
+ if(peerId.empty()) {
+ peerId = generatePeerId(peerIdPrefix, randomizer);
+ }
+ return peerId;
+}
+
+void setStaticPeerId(const std::string& newPeerId)
+{
+ peerId = newPeerId;
+}
+
+// If PeerID is not generated, it is created with default peerIdPrefix
+// (-aria2-) and SimpleRandomizer.
+const unsigned char* getStaticPeerId()
+{
+ if(peerId.empty()) {
+ return
+ reinterpret_cast<const unsigned char*>(generateStaticPeerId(DEFAULT_PEER_ID_PREFIX, SimpleRandomizer::getInstance()).data());
+ } else {
+ return reinterpret_cast<const unsigned char*>(peerId.data());
+ }
+}
+
+} // namespace bittorrent
+
+} // namespace aria2
diff --git a/src/bittorrent_helper.h b/src/bittorrent_helper.h
new file mode 100644
index 00000000..99db7d9a
--- /dev/null
+++ b/src/bittorrent_helper.h
@@ -0,0 +1,132 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2009 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_BITTORRENT_HELPER_H_
+#define _D_BITTORRENT_HELPER_H_
+
+#include "common.h"
+
+#include <string>
+#include <vector>
+
+#include "SharedHandle.h"
+#include "AnnounceTier.h"
+#include "BDE.h"
+#include "Util.h"
+
+namespace aria2 {
+
+class DownloadContext;
+class Randomizer;
+
+namespace bittorrent {
+
+extern const std::string INFO_HASH;
+
+extern const std::string MODE;
+
+extern const std::string PRIVATE;
+
+extern const std::string ANNOUNCE_LIST;
+
+extern const std::string NODES;
+
+extern const std::string HOSTNAME;
+
+extern const std::string PORT;
+
+extern const std::string NAME;
+
+extern const std::string SINGLE;
+
+extern const std::string MULTI;
+
+extern const std::string BITTORRENT;
+
+void load(const std::string& torrentFile,
+ const SharedHandle<DownloadContext>& ctx,
+ const std::string& overrideName = "");
+
+void loadFromMemory(const unsigned char* content, size_t length,
+ const SharedHandle<DownloadContext>& ctx,
+ const std::string& defaultName,
+ const std::string& overrideName = "");
+
+void loadFromMemory(const std::string& context,
+ const SharedHandle<DownloadContext>& ctx,
+ const std::string& defaultName,
+ const std::string& overrideName = "");
+
+// Generates Peer ID. BitTorrent specification says Peer ID is 20-byte
+// length. This function uses peerIdPrefix as a Peer ID and it is
+// less than 20bytes, random bytes are generated and appened to it. If
+// peerIdPrefix is larger than 20bytes, first 20bytes are used.
+std::string generatePeerId
+(const std::string& peerIdPrefix, const SharedHandle<Randomizer>& randomizer);
+
+// Generates Peer ID and stores it in static variable. This function
+// uses generatePeerId(peerIdPrefix, randomizer) to produce Peer ID.
+const std::string& generateStaticPeerId
+(const std::string& peerIdPrefix, const SharedHandle<Randomizer>& randomizer);
+
+// Returns Peer ID statically stored by generateStaticPeerId(). If
+// Peer ID is not stored yet, this function calls
+// generateStaticPeerId("-aria2-", randomizer)
+const unsigned char* getStaticPeerId();
+
+// Set newPeerId as a static Peer ID. newPeerId must be 20-byte
+// length.
+void setStaticPeerId(const std::string& newPeerId);
+
+// Computes fast set index and stores them in fastset.
+void computeFastSet
+(std::vector<size_t>& fastSet, const std::string& ipaddr,
+ size_t numPieces, const unsigned char* infoHash, size_t fastSetSize);
+
+// Writes the detailed information about torrent loaded in dctx.
+void print(std::ostream& o, const SharedHandle<DownloadContext>& dctx);
+
+// Returns the value associated with INFO_HASH key in BITTORRENT
+// attribute.
+const unsigned char*
+getInfoHash(const SharedHandle<DownloadContext>& downloadContext);
+
+std::string
+getInfoHashString(const SharedHandle<DownloadContext>& downloadContext);
+
+} // namespace bittorrent
+
+} // namespace aria2
+
+#endif // _D_BITTORRENT_HELPER_H_
diff --git a/src/download_helper.cc b/src/download_helper.cc
index b232f33d..baabf94e 100644
--- a/src/download_helper.cc
+++ b/src/download_helper.cc
@@ -48,12 +48,11 @@
#include "ParameterizedStringParser.h"
#include "PStringBuildVisitor.h"
#include "UriListParser.h"
-#include "SingleFileDownloadContext.h"
+#include "DownloadContext.h"
#include "RecoverableException.h"
#include "DlAbortEx.h"
#include "message.h"
#include "StringFormat.h"
-#include "DefaultBtContext.h"
#include "FileEntry.h"
#include "LogFactory.h"
#include "File.h"
@@ -62,6 +61,9 @@
#include "OptionHandler.h"
#include "ByteArrayDiskWriter.h"
#include "a2functional.h"
+#ifdef ENABLE_BITTORRENT
+# include "bittorrent_helper.h"
+#endif // ENABLE_BITTORRENT
namespace aria2 {
@@ -178,16 +180,14 @@ static SharedHandle<RequestGroup> createRequestGroup
bool useOutOption = false)
{
SharedHandle<RequestGroup> rg(new RequestGroup(option, uris));
- SharedHandle<SingleFileDownloadContext> dctx
- (new SingleFileDownloadContext
+ SharedHandle<DownloadContext> dctx
+ (new DownloadContext
(option->getAsInt(PREF_SEGMENT_SIZE),
0,
- A2STR::NIL,
useOutOption&&!option->blank(PREF_OUT)?
strconcat(option->get(PREF_DIR), "/", option->get(PREF_OUT)):A2STR::NIL));
-
dctx->setDir(option->get(PREF_DIR));
- dctx->getFileEntries().front()->setUris(uris);
+ dctx->getFirstFileEntry()->setUris(uris);
rg->setDownloadContext(dctx);
return rg;
}
@@ -202,28 +202,26 @@ createBtRequestGroup(const std::string& torrentFilePath,
const std::string& torrentData = "")
{
SharedHandle<RequestGroup> rg(new RequestGroup(option, auxUris));
- SharedHandle<DefaultBtContext> btContext(new DefaultBtContext());
- btContext->setDir(option->get(PREF_DIR));
+ SharedHandle<DownloadContext> dctx(new DownloadContext());
+ dctx->setDir(option->get(PREF_DIR));
if(torrentData.empty()) {
- btContext->load(torrentFilePath);// may throw exception
+ bittorrent::load(torrentFilePath, dctx);// may throw exception
} else {
- btContext->loadFromMemory(torrentData, "default"); // may throw exception
- }
- if(option->defined(PREF_PEER_ID_PREFIX)) {
- btContext->setPeerIdPrefix(option->get(PREF_PEER_ID_PREFIX));
+ bittorrent::loadFromMemory(torrentData, dctx, "default"); // may
+ // throw
+ // exception
}
- btContext->setFileFilter
- (Util::parseIntRange(option->get(PREF_SELECT_FILE)));
+ dctx->setFileFilter(Util::parseIntRange(option->get(PREF_SELECT_FILE)));
std::istringstream indexOutIn(option->get(PREF_INDEX_OUT));
std::map<size_t, std::string> indexPathMap =
Util::createIndexPathMap(indexOutIn);
for(std::map<size_t, std::string>::const_iterator i = indexPathMap.begin();
i != indexPathMap.end(); ++i) {
- btContext->setFilePathWithIndex
- ((*i).first, strconcat(btContext->getDir(), "/", (*i).second));
+ dctx->setFilePathWithIndex
+ ((*i).first, strconcat(dctx->getDir(), "/", (*i).second));
}
- rg->setDownloadContext(btContext);
- btContext->setOwnerRequestGroup(rg.get());
+ rg->setDownloadContext(dctx);
+ dctx->setOwnerRequestGroup(rg.get());
return rg;
}
diff --git a/src/main.cc b/src/main.cc
index 1c4210bd..a3a13ffb 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -59,7 +59,6 @@
#include "a2io.h"
#include "a2time.h"
#include "Platform.h"
-#include "DefaultBtContext.h"
#include "FileEntry.h"
#include "RequestGroup.h"
#include "ConsoleStatCalc.h"
@@ -69,6 +68,10 @@
#include "ProtocolDetector.h"
#include "RecoverableException.h"
#include "SocketCore.h"
+#include "DownloadContext.h"
+#ifdef ENABLE_BITTORRENT
+# include "bittorrent_helper.h"
+#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
# include "MetalinkHelper.h"
# include "MetalinkEntry.h"
@@ -108,9 +111,9 @@ std::ostream& getSummaryOut(const SharedHandle<Option>& op)
#ifdef ENABLE_BITTORRENT
static void showTorrentFile(const std::string& uri)
{
- SharedHandle<DefaultBtContext> btContext(new DefaultBtContext());
- btContext->load(uri);
- std::cout << btContext << std::endl;
+ SharedHandle<DownloadContext> dctx(new DownloadContext());
+ bittorrent::load(uri, dctx);
+ bittorrent::print(std::cout, dctx);
}
#endif // ENABLE_BITTORRENT
@@ -122,7 +125,7 @@ static void showMetalinkFile
MetalinkHelper::parseAndQuery(metalinkEntries, uri, op.get());
std::deque<SharedHandle<FileEntry> > fileEntries;
MetalinkEntry::toFileEntry(fileEntries, metalinkEntries);
- Util::toStream(std::cout, fileEntries);
+ Util::toStream(fileEntries.begin(), fileEntries.end(), std::cout);
std::cout << std::endl;
}
#endif // ENABLE_METALINK
diff --git a/src/option_processing.cc b/src/option_processing.cc
index 8b27f197..240f2bac 100644
--- a/src/option_processing.cc
+++ b/src/option_processing.cc
@@ -54,6 +54,8 @@
#include "StringFormat.h"
#include "OptionHandlerException.h"
#include "DownloadResult.h"
+#include "SimpleRandomizer.h"
+#include "bittorrent_helper.h"
namespace aria2 {
@@ -202,6 +204,10 @@ void option_processing(Option& op, std::deque<std::string>& uris,
}
}
#endif // HAVE_DAEMON
+#ifdef ENABLE_BITTORRENT
+ bittorrent::generateStaticPeerId(op.get(PREF_PEER_ID_PREFIX),
+ SimpleRandomizer::getInstance());
+#endif // ENABLE_BITTORRENT
}
} // namespace aria2