util::parseIntSegments: Return SegList<int>

pull/235/merge
Tatsuhiro Tsujikawa 2014-06-04 23:21:01 +09:00
parent 007b890fe4
commit c0e4381780
14 changed files with 71 additions and 86 deletions

View File

@ -195,8 +195,8 @@ void BtSetup::setup(std::vector<std::unique_ptr<Command>>& commands,
sgl.add(usedPort, usedPort+1);
ret = command->bindPort(port, sgl);
} else {
SegList<int> sgl;
util::parseIntSegments(sgl, e->getOption()->get(PREF_LISTEN_PORT));
auto sgl = util::parseIntSegments
(e->getOption()->get(PREF_LISTEN_PORT));
sgl.normalize();
ret = command->bindPort(port, sgl);
}

View File

@ -123,8 +123,8 @@ std::vector<std::unique_ptr<Command>> DHTSetup::setup
// this. We did the same thing in TCP socket. See BtSetup.cc.
bool rv;
if(port == 0) {
SegList<int> sgl;
util::parseIntSegments(sgl, e->getOption()->get(PREF_DHT_LISTEN_PORT));
auto sgl =
util::parseIntSegments(e->getOption()->get(PREF_DHT_LISTEN_PORT));
sgl.normalize();
rv = connection->bind(port, addr, sgl);
} else {

View File

@ -123,7 +123,7 @@ void DownloadContext::setFilePathWithIndex
}
}
void DownloadContext::setFileFilter(SegList<int>& sgl)
void DownloadContext::setFileFilter(SegList<int> sgl)
{
using namespace std::placeholders;

View File

@ -183,7 +183,7 @@ public:
}
// sgl must be normalized before the call.
void setFileFilter(SegList<int>& sgl);
void setFileFilter(SegList<int> sgl);
// Sets file path for specified index. index starts from 1. The
// index is the same used in setFileFilter(). path is not escaped by

View File

@ -186,8 +186,7 @@ Metalink2RequestGroup::createRequestGroup
(preferredProtocol, -MetalinkResource::getLowestPriority());
}
}
SegList<int> sgl;
util::parseIntSegments(sgl, optionTemplate->get(PREF_SELECT_FILE));
auto sgl = util::parseIntSegments(optionTemplate->get(PREF_SELECT_FILE));
sgl.normalize();
if(sgl.hasNext()) {
size_t inspoint = 0;

View File

@ -117,8 +117,7 @@ IntegerRangeOptionHandler::~IntegerRangeOptionHandler() {}
void IntegerRangeOptionHandler::parseArg
(Option& option, const std::string& optarg) const
{
SegList<int> sgl;
util::parseIntSegments(sgl, optarg);
auto sgl = util::parseIntSegments(optarg);
sgl.normalize();
while(sgl.hasNext()) {
int v = sgl.next();

View File

@ -1457,10 +1457,9 @@ void changeOption
dctx->setDigest(hashType, util::fromHex(p.second.first, p.second.second));
}
if(option.defined(PREF_SELECT_FILE)) {
SegList<int> sgl;
util::parseIntSegments(sgl, grOption->get(PREF_SELECT_FILE));
auto sgl = util::parseIntSegments(grOption->get(PREF_SELECT_FILE));
sgl.normalize();
dctx->setFileFilter(sgl);
dctx->setFileFilter(std::move(sgl));
}
if(option.defined(PREF_SPLIT)) {
group->setNumConcurrentCommand(grOption->getAsInt(PREF_SPLIT));

View File

@ -49,6 +49,12 @@ public:
: index_(0), val_(std::numeric_limits<T>::min())
{}
// Don't allow copying
SegList(const SegList&) = delete;
SegList& operator=(const SegList&) = delete;
SegList(SegList&&) = default;
void clear()
{
segs_.clear();
@ -62,11 +68,11 @@ public:
void normalize()
{
if(!segs_.empty()) {
std::sort(segs_.begin(), segs_.end());
std::vector<std::pair<T, T> > s;
std::sort(std::begin(segs_), std::end(segs_));
std::vector<std::pair<T, T>> s;
s.push_back(segs_.front());
for(size_t i = 1, len = segs_.size(); i < len; ++i) {
const std::pair<T, T>& x = segs_[i];
auto& x = segs_[i];
if(x.first <= s.back().second) {
if(s.back().second < x.second) {
s.back().second = x.second;
@ -88,7 +94,7 @@ public:
if(segs_.empty()) {
val_ = std::max(val_, a);
}
segs_.push_back(std::make_pair(a, b));
segs_.emplace_back(a, b);
}
}
@ -103,7 +109,7 @@ public:
T next()
{
T res;
size_t len = segs_.size();
auto len = segs_.size();
if(index_ < len) {
res = val_++;
if(val_ == segs_[index_].second) {
@ -131,12 +137,9 @@ public:
return res;
}
private:
std::vector<std::pair<T, T> > segs_;
std::vector<std::pair<T, T>> segs_;
size_t index_;
T val_;
// Don't allow copying
SegList(const SegList<T>&);
SegList& operator=(const SegList<T>&);
};
} // namespace aria2

View File

@ -201,10 +201,9 @@ createBtRequestGroup(const std::string& metaInfoUri,
if(adjustAnnounceUri) {
bittorrent::adjustAnnounceUri(bittorrent::getTorrentAttrs(dctx), option);
}
SegList<int> sgl;
util::parseIntSegments(sgl, option->get(PREF_SELECT_FILE));
auto sgl = util::parseIntSegments(option->get(PREF_SELECT_FILE));
sgl.normalize();
dctx->setFileFilter(sgl);
dctx->setFileFilter(std::move(sgl));
std::istringstream indexOutIn(option->get(PREF_INDEX_OUT));
auto indexPaths = util::createIndexPaths(indexOutIn);
for(const auto& i : indexPaths) {

View File

@ -584,8 +584,9 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
}
}
void parseIntSegments(SegList<int>& sgl, const std::string& src)
SegList<int> parseIntSegments(const std::string& src)
{
SegList<int> sgl;
for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;) {
std::string::const_iterator j = std::find(i, eoi, ',');
if(j == i) {
@ -616,6 +617,7 @@ void parseIntSegments(SegList<int>& sgl, const std::string& src)
}
i = j+1;
}
return sgl;
}
namespace {

View File

@ -277,7 +277,7 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10);
bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10);
void parseIntSegments(SegList<int>& sgl, const std::string& src);
SegList<int> parseIntSegments(const std::string& src);
// Parses string which specifies the range of piece index for higher
// priority and appends those indexes into result. The input string

View File

@ -652,20 +652,16 @@ void BittorrentHelperTest::testSetFileFilter_single()
load(A2_TEST_DIR"/single.torrent", dctx, option_);
CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
SegList<int> sgl;
dctx->setFileFilter(sgl);
dctx->setFileFilter(SegList<int>());
CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
sgl.clear();
sgl.add(1, 2);
dctx->setFileFilter(sgl);
dctx->setFileFilter(util::parseIntSegments("1,2"));
CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
// For single file torrent, file is always selected whatever range
// is passed.
sgl.clear();
sgl.add(2, 3);
dctx->setFileFilter(sgl);
dctx->setFileFilter(util::parseIntSegments("2,3"));
CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
}
@ -677,25 +673,19 @@ void BittorrentHelperTest::testSetFileFilter_multi()
CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
SegList<int> sgl;
dctx->setFileFilter(sgl);
dctx->setFileFilter(SegList<int>());
CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
sgl.add(2, 3);
dctx->setFileFilter(sgl);
dctx->setFileFilter(util::parseIntSegments("2,3"));
CPPUNIT_ASSERT(!dctx->getFileEntries()[0]->isRequested());
CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
sgl.clear();
sgl.add(3, 4);
dctx->setFileFilter(sgl);
dctx->setFileFilter(util::parseIntSegments("3,4"));
CPPUNIT_ASSERT(!dctx->getFileEntries()[0]->isRequested());
CPPUNIT_ASSERT(!dctx->getFileEntries()[1]->isRequested());
sgl.clear();
util::parseIntSegments(sgl, "1,2");
dctx->setFileFilter(sgl);
dctx->setFileFilter(util::parseIntSegments("1,2"));
CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
}

View File

@ -83,10 +83,9 @@ void DownloadContextTest::testSetFileFilter()
files.push_back(std::shared_ptr<FileEntry>(new FileEntry("file", 1, i)));
}
ctx.setFileEntries(files.begin(), files.end());
SegList<int> sgl;
util::parseIntSegments(sgl, "6-8,2-4");
auto sgl = util::parseIntSegments("6-8,2-4");
sgl.normalize();
ctx.setFileFilter(sgl);
ctx.setFileFilter(std::move(sgl));
const std::vector<std::shared_ptr<FileEntry> >& res = ctx.getFileEntries();
CPPUNIT_ASSERT(!res[0]->isRequested());
CPPUNIT_ASSERT(res[1]->isRequested());

View File

@ -1669,70 +1669,65 @@ void UtilTest::testConvertBitfield()
void UtilTest::testParseIntSegments()
{
SegList<int> sgl;
util::parseIntSegments(sgl, "1,3-8,10");
{
auto sgl = util::parseIntSegments("1,3-8,10");
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(1, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(3, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(4, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(5, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(6, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(7, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(8, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(10, sgl.next());
CPPUNIT_ASSERT(!sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(0, sgl.next());
sgl.clear();
util::parseIntSegments(sgl, ",,,1,,,3,,,");
CPPUNIT_ASSERT_EQUAL(1, sgl.next());
CPPUNIT_ASSERT_EQUAL(3, sgl.next());
CPPUNIT_ASSERT(!sgl.hasNext());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(1, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(3, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(4, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(5, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(6, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(7, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(8, sgl.next());
CPPUNIT_ASSERT(sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(10, sgl.next());
CPPUNIT_ASSERT(!sgl.hasNext());
CPPUNIT_ASSERT_EQUAL(0, sgl.next());
}
{
auto sgl = util::parseIntSegments(",,,1,,,3,,,");
CPPUNIT_ASSERT_EQUAL(1, sgl.next());
CPPUNIT_ASSERT_EQUAL(3, sgl.next());
CPPUNIT_ASSERT(!sgl.hasNext());
}
}
void UtilTest::testParseIntSegments_invalidRange()
{
try {
SegList<int> sgl;
util::parseIntSegments(sgl, "-1");
auto sgl = util::parseIntSegments("-1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
SegList<int> sgl;
util::parseIntSegments(sgl, "1-");
auto sgl = util::parseIntSegments("1-");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
SegList<int> sgl;
util::parseIntSegments(sgl, "2147483648");
auto sgl = util::parseIntSegments("2147483648");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
SegList<int> sgl;
util::parseIntSegments(sgl, "2147483647-2147483648");
auto sgl = util::parseIntSegments("2147483647-2147483648");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
SegList<int> sgl;
util::parseIntSegments(sgl, "1-2x");
auto sgl = util::parseIntSegments("1-2x");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
SegList<int> sgl;
util::parseIntSegments(sgl, "3x-4");
auto sgl = util::parseIntSegments("3x-4");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}