mirror of https://github.com/aria2/aria2
2009-05-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Selecting files are now done in DefaultBtContext::setFileFileter(). PieceStorage::setFileFilter(), DiskAdaptor::addDownloadEntry() functions are removed because they are no longer used. Creating filter in BitfieldMan is done in new funtion PieceStorage::setupFileFilter() * src/BtContext.cc * src/BtContext.h * src/DefaultBtContext.cc * src/DefaultBtContext.h * src/DefaultPieceStorage.cc * src/DefaultPieceStorage.h * src/DiskAdaptor.cc * src/DiskAdaptor.h * src/PieceStorage.h * src/RequestGroup.cc * src/UnknownLengthPieceStorage.h * src/XmlRpcMethodImpl.cc * test/DefaultBtContextTest.cc * test/MockBtContext.h * test/MockPieceStorage.hpull/1/head
parent
c3129fd4a4
commit
2758562eb0
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
|||
2009-05-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Selecting files are now done in
|
||||
DefaultBtContext::setFileFileter().
|
||||
PieceStorage::setFileFilter(), DiskAdaptor::addDownloadEntry()
|
||||
functions are removed because they are no longer used. Creating
|
||||
filter in BitfieldMan is done in new funtion
|
||||
PieceStorage::setupFileFilter()
|
||||
* src/BtContext.cc
|
||||
* src/BtContext.h
|
||||
* src/DefaultBtContext.cc
|
||||
* src/DefaultBtContext.h
|
||||
* src/DefaultPieceStorage.cc
|
||||
* src/DefaultPieceStorage.h
|
||||
* src/DiskAdaptor.cc
|
||||
* src/DiskAdaptor.h
|
||||
* src/PieceStorage.h
|
||||
* src/RequestGroup.cc
|
||||
* src/UnknownLengthPieceStorage.h
|
||||
* src/XmlRpcMethodImpl.cc
|
||||
* test/DefaultBtContextTest.cc
|
||||
* test/MockBtContext.h
|
||||
* test/MockPieceStorage.h
|
||||
|
||||
2009-05-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Fixed compile error on Mac OS X
|
||||
|
|
|
@ -62,14 +62,4 @@ const std::string BtContext::C_ANNOUNCE_LIST("announce-list");
|
|||
|
||||
const std::string BtContext::C_NODES("nodes");
|
||||
|
||||
void BtContext::setFileFilter(const IntSequence& seq)
|
||||
{
|
||||
_fileFilter = seq;
|
||||
}
|
||||
|
||||
IntSequence BtContext::getFileFilter() const
|
||||
{
|
||||
return _fileFilter;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#define _D_BT_CONTEXT_H_
|
||||
|
||||
#include "DownloadContext.h"
|
||||
|
||||
#include <utility>
|
||||
#include <deque>
|
||||
|
||||
|
@ -49,8 +50,6 @@ class RequestGroup;
|
|||
class BtContext:public DownloadContext {
|
||||
protected:
|
||||
bool _private;
|
||||
|
||||
IntSequence _fileFilter;
|
||||
public:
|
||||
BtContext():_private(false) {}
|
||||
|
||||
|
@ -87,9 +86,7 @@ public:
|
|||
|
||||
virtual const std::string& getName() const = 0;
|
||||
|
||||
void setFileFilter(const IntSequence& seq);
|
||||
|
||||
IntSequence getFileFilter() const;
|
||||
virtual void setFileFilter(IntSequence seq) = 0;
|
||||
|
||||
static const std::string C_NAME;
|
||||
|
||||
|
|
|
@ -514,4 +514,22 @@ void DefaultBtContext::setFilePathWithIndex
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "IntSequence.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class Randomizer;
|
||||
|
@ -160,6 +162,8 @@ private:
|
|||
|
||||
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)
|
||||
|
|
|
@ -358,12 +358,6 @@ bool DefaultPieceStorage::isSelectiveDownloadingMode()
|
|||
return bitfieldMan->isFilterEnabled();
|
||||
}
|
||||
|
||||
void DefaultPieceStorage::finishSelectiveDownloadingMode()
|
||||
{
|
||||
bitfieldMan->clearFilter();
|
||||
diskAdaptor->addAllDownloadEntry();
|
||||
}
|
||||
|
||||
// not unittested
|
||||
void DefaultPieceStorage::cancelPiece(const PieceHandle& piece)
|
||||
{
|
||||
|
@ -420,45 +414,34 @@ size_t DefaultPieceStorage::getInFlightPieceCompletedLength() const
|
|||
}
|
||||
|
||||
// not unittested
|
||||
void DefaultPieceStorage::setFileFilter(const std::deque<std::string>& filePaths)
|
||||
void DefaultPieceStorage::setupFileFilter()
|
||||
{
|
||||
if(downloadContext->getFileMode() != DownloadContext::MULTI || filePaths.empty()) {
|
||||
std::deque<SharedHandle<FileEntry> > fileEntries =
|
||||
downloadContext->getFileEntries();
|
||||
bool allSelected = true;
|
||||
for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
|
||||
fileEntries.begin(); i != fileEntries.end(); ++i) {
|
||||
if(!(*i)->isRequested()) {
|
||||
allSelected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(allSelected) {
|
||||
return;
|
||||
}
|
||||
diskAdaptor->removeAllDownloadEntry();
|
||||
for(std::deque<std::string>::const_iterator pitr = filePaths.begin();
|
||||
pitr != filePaths.end(); pitr++) {
|
||||
if(!diskAdaptor->addDownloadEntry(*pitr)) {
|
||||
throw DlAbortEx(StringFormat(EX_NO_SUCH_FILE_ENTRY, (*pitr).c_str()).str());
|
||||
for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
|
||||
fileEntries.begin(); i != fileEntries.end(); ++i) {
|
||||
if((*i)->isRequested()) {
|
||||
bitfieldMan->addFilter((*i)->getOffset(), (*i)->getLength());
|
||||
}
|
||||
FileEntryHandle fileEntry = diskAdaptor->getFileEntryFromPath(*pitr);
|
||||
bitfieldMan->addFilter(fileEntry->getOffset(), fileEntry->getLength());
|
||||
}
|
||||
bitfieldMan->enableFilter();
|
||||
}
|
||||
|
||||
void DefaultPieceStorage::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());
|
||||
std::deque<std::string> filePaths;
|
||||
const FileEntries& entries = diskAdaptor->getFileEntries();
|
||||
int32_t entriesSize = entries.size();
|
||||
for(int32_t i = 0; i < entriesSize; i++) {
|
||||
if(std::binary_search(fileIndexes.begin(), fileIndexes.end(), i+1)) {
|
||||
logger->debug("index=%d is %s", i+1, entries[i]->getPath().c_str());
|
||||
filePaths.push_back(entries[i]->getPath());
|
||||
}
|
||||
}
|
||||
setFileFilter(filePaths);
|
||||
}
|
||||
|
||||
// not unittested
|
||||
void DefaultPieceStorage::clearFileFilter()
|
||||
{
|
||||
bitfieldMan->clearFilter();
|
||||
diskAdaptor->addAllDownloadEntry();
|
||||
}
|
||||
|
||||
// not unittested
|
||||
|
|
|
@ -151,9 +151,7 @@ public:
|
|||
|
||||
virtual void initStorage();
|
||||
|
||||
virtual void setFileFilter(const std::deque<std::string>& filePaths);
|
||||
|
||||
virtual void setFileFilter(IntSequence seq);
|
||||
virtual void setupFileFilter();
|
||||
|
||||
virtual void clearFileFilter();
|
||||
|
||||
|
@ -178,8 +176,6 @@ public:
|
|||
|
||||
virtual bool isSelectiveDownloadingMode();
|
||||
|
||||
virtual void finishSelectiveDownloadingMode();
|
||||
|
||||
virtual bool isEndGame();
|
||||
|
||||
virtual SharedHandle<DiskAdaptor> getDiskAdaptor();
|
||||
|
|
|
@ -36,9 +36,6 @@
|
|||
#include "FileEntry.h"
|
||||
#include "LogFactory.h"
|
||||
#include "Logger.h"
|
||||
#include "message.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "StringFormat.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -50,54 +47,6 @@ DiskAdaptor::DiskAdaptor():
|
|||
|
||||
DiskAdaptor::~DiskAdaptor() {}
|
||||
|
||||
FileEntryHandle DiskAdaptor::getFileEntryFromPath(const std::string& fileEntryPath) const
|
||||
{
|
||||
for(FileEntries::const_iterator itr = fileEntries.begin();
|
||||
itr != fileEntries.end(); itr++) {
|
||||
if((*itr)->getPath() == fileEntryPath) {
|
||||
return *itr;
|
||||
}
|
||||
}
|
||||
throw DlAbortEx(StringFormat(EX_NO_SUCH_FILE_ENTRY, fileEntryPath.c_str()).str());
|
||||
}
|
||||
|
||||
bool DiskAdaptor::addDownloadEntry(const std::string& fileEntryPath)
|
||||
{
|
||||
for(FileEntries::iterator itr = fileEntries.begin();
|
||||
itr != fileEntries.end(); itr++) {
|
||||
if((*itr)->getPath() == fileEntryPath) {
|
||||
(*itr)->setRequested(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DiskAdaptor::addDownloadEntry(size_t index)
|
||||
{
|
||||
if(fileEntries.size() <= index) {
|
||||
return false;
|
||||
}
|
||||
fileEntries[index]->setRequested(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DiskAdaptor::addAllDownloadEntry()
|
||||
{
|
||||
for(FileEntries::iterator itr = fileEntries.begin();
|
||||
itr != fileEntries.end(); itr++) {
|
||||
(*itr)->setRequested(true);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskAdaptor::removeAllDownloadEntry()
|
||||
{
|
||||
for(FileEntries::iterator itr = fileEntries.begin();
|
||||
itr != fileEntries.end(); itr++) {
|
||||
(*itr)->setRequested(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskAdaptor::setFileEntries(const FileEntries& fileEntries) {
|
||||
this->fileEntries = fileEntries;
|
||||
}
|
||||
|
|
|
@ -36,10 +36,12 @@
|
|||
#define _D_DISK_ADAPTOR_H_
|
||||
|
||||
#include "BinaryStream.h"
|
||||
#include "TimeA2.h"
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
#include "TimeA2.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class FileEntry;
|
||||
|
@ -73,18 +75,8 @@ public:
|
|||
|
||||
void setFileEntries(const std::deque<SharedHandle<FileEntry> >& fileEntries);
|
||||
|
||||
SharedHandle<FileEntry> getFileEntryFromPath(const std::string& fileEntryPath) const;
|
||||
|
||||
const std::deque<SharedHandle<FileEntry> >& getFileEntries() const;
|
||||
|
||||
bool addDownloadEntry(const std::string& fileEntryPath);
|
||||
|
||||
bool addDownloadEntry(size_t index);
|
||||
|
||||
void addAllDownloadEntry();
|
||||
|
||||
void removeAllDownloadEntry();
|
||||
|
||||
virtual SharedHandle<FileAllocationIterator> fileAllocationIterator() = 0;
|
||||
|
||||
virtual void enableDirectIO() {}
|
||||
|
|
|
@ -143,9 +143,7 @@ public:
|
|||
|
||||
virtual uint64_t getFilteredCompletedLength() = 0;
|
||||
|
||||
virtual void setFileFilter(const std::deque<std::string>& filePaths) = 0;
|
||||
|
||||
virtual void setFileFilter(IntSequence seq) = 0;
|
||||
virtual void setupFileFilter() = 0;
|
||||
|
||||
virtual void clearFileFilter() = 0;
|
||||
|
||||
|
@ -177,8 +175,6 @@ public:
|
|||
|
||||
virtual bool isSelectiveDownloadingMode() = 0;
|
||||
|
||||
virtual void finishSelectiveDownloadingMode() = 0;
|
||||
|
||||
virtual bool isEndGame() = 0;
|
||||
|
||||
virtual SharedHandle<DiskAdaptor> getDiskAdaptor() = 0;
|
||||
|
|
|
@ -230,7 +230,7 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
|
|||
_logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
|
||||
_uris.clear();
|
||||
|
||||
_pieceStorage->setFileFilter(btContext->getFileFilter());
|
||||
_pieceStorage->setupFileFilter();
|
||||
} else if(btContext->getFileEntries().size() == 1) {
|
||||
// web-seeding is only enabled for single file torrent
|
||||
SharedHandle<FileEntry> fileEntry = btContext->getFileEntries().front();
|
||||
|
|
|
@ -152,9 +152,7 @@ public:
|
|||
return getCompletedLength();
|
||||
}
|
||||
|
||||
virtual void setFileFilter(const std::deque<std::string>& filePaths) {}
|
||||
|
||||
virtual void setFileFilter(IntSequence seq) {}
|
||||
virtual void setupFileFilter() {}
|
||||
|
||||
virtual void clearFileFilter() {}
|
||||
|
||||
|
@ -201,8 +199,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual void finishSelectiveDownloadingMode() {}
|
||||
|
||||
virtual bool isEndGame()
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -265,38 +265,16 @@ BDE GetFilesXmlRpcMethod::process
|
|||
(StringFormat("No file data is available for GID#%d", gid).str());
|
||||
}
|
||||
BDE files = BDE::list();
|
||||
SharedHandle<BtContext> btctx =
|
||||
dynamic_pointer_cast<BtContext>(group->getDownloadContext());
|
||||
if(btctx.isNull()) {
|
||||
std::deque<SharedHandle<FileEntry> > fileEntries =
|
||||
group->getDownloadContext()->getFileEntries();
|
||||
size_t index = 1;
|
||||
for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
|
||||
fileEntries.begin(); i != fileEntries.end(); ++i, ++index) {
|
||||
BDE entry = BDE::dict();
|
||||
entry["index"] = BDE("1");
|
||||
entry["path"] = group->getDownloadContext()->getActualBasePath();
|
||||
entry["selected"] = BDE("true");
|
||||
entry["index"] = Util::uitos(index);
|
||||
entry["path"] = (*i)->getPath();
|
||||
entry["selected"] = (*i)->isRequested()?BDE("true"):BDE("false");
|
||||
files << entry;
|
||||
} else {
|
||||
std::deque<int32_t> fileIndexes = btctx->getFileFilter().flush();
|
||||
std::sort(fileIndexes.begin(), fileIndexes.end());
|
||||
fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()),
|
||||
fileIndexes.end());
|
||||
std::deque<SharedHandle<FileEntry> > fileEntries =
|
||||
btctx->getFileEntries();
|
||||
|
||||
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) {
|
||||
BDE entry = BDE::dict();
|
||||
entry["index"] = Util::itos(index);
|
||||
entry["path"] = (*i)->getPath();
|
||||
if(selectAll ||
|
||||
std::binary_search(fileIndexes.begin(), fileIndexes.end(), index)) {
|
||||
entry["selected"] = BDE("true");
|
||||
} else {
|
||||
entry["selected"] = BDE("false");
|
||||
}
|
||||
files << entry;
|
||||
}
|
||||
}
|
||||
BDE resParams = BDE::list();
|
||||
resParams << files;
|
||||
|
|
|
@ -44,6 +44,8 @@ class DefaultBtContextTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testLoadFromMemory_joinPathSingle);
|
||||
CPPUNIT_TEST(testGetNodes);
|
||||
CPPUNIT_TEST(testGetActualBasePath);
|
||||
CPPUNIT_TEST(testSetFileFilter_single);
|
||||
CPPUNIT_TEST(testSetFileFilter_multi);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
public:
|
||||
void setUp() {
|
||||
|
@ -76,6 +78,8 @@ public:
|
|||
void testLoadFromMemory_joinPathSingle();
|
||||
void testGetNodes();
|
||||
void testGetActualBasePath();
|
||||
void testSetFileFilter_single();
|
||||
void testSetFileFilter_multi();
|
||||
};
|
||||
|
||||
|
||||
|
@ -548,4 +552,48 @@ void DefaultBtContextTest::testGetActualBasePath()
|
|||
multiCtx.getActualBasePath());
|
||||
}
|
||||
|
||||
void DefaultBtContextTest::testSetFileFilter_single()
|
||||
{
|
||||
DefaultBtContext ctx;
|
||||
ctx.load("single.torrent");
|
||||
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
|
||||
ctx.setFileFilter(Util::parseIntRange(""));
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
|
||||
ctx.setFileFilter(Util::parseIntRange("1"));
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
|
||||
// For single file torrent, file is always selected whatever range
|
||||
// is passed.
|
||||
ctx.setFileFilter(Util::parseIntRange("2"));
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
}
|
||||
|
||||
void DefaultBtContextTest::testSetFileFilter_multi()
|
||||
{
|
||||
DefaultBtContext ctx;
|
||||
ctx.load("test.torrent");
|
||||
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
|
||||
|
||||
ctx.setFileFilter(Util::parseIntRange(""));
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
|
||||
|
||||
ctx.setFileFilter(Util::parseIntRange("2"));
|
||||
CPPUNIT_ASSERT(!ctx.getFileEntries()[0]->isRequested());
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
|
||||
|
||||
ctx.setFileFilter(Util::parseIntRange("3"));
|
||||
CPPUNIT_ASSERT(!ctx.getFileEntries()[0]->isRequested());
|
||||
CPPUNIT_ASSERT(!ctx.getFileEntries()[1]->isRequested());
|
||||
|
||||
ctx.setFileFilter(Util::parseIntRange("1,2"));
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
|
||||
CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -170,6 +170,7 @@ public:
|
|||
_nodes = nodes;
|
||||
}
|
||||
|
||||
virtual void setFileFilter(IntSequence seq) {}
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -121,9 +121,7 @@ public:
|
|||
this->filteredCompletedLength = completedLength;
|
||||
}
|
||||
|
||||
virtual void setFileFilter(const std::deque<std::string>& filePaths) {}
|
||||
|
||||
virtual void setFileFilter(IntSequence seq) {}
|
||||
virtual void setupFileFilter() {}
|
||||
|
||||
virtual void clearFileFilter() {}
|
||||
|
||||
|
@ -167,8 +165,6 @@ public:
|
|||
this->selectiveDownloadingMode = flag;
|
||||
}
|
||||
|
||||
virtual void finishSelectiveDownloadingMode() {}
|
||||
|
||||
virtual bool isEndGame() {
|
||||
return endGame;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue