diff --git a/ChangeLog b/ChangeLog index 56e6180d..0d459bcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-06-24 Tatsuhiro Tsujikawa + + Added tellWaiting XML-RPC method. + * src/SingleFileDownloadContext.cc + * src/XmlRpcMethodFactory.cc + * src/XmlRpcMethodImpl.cc + * src/XmlRpcMethodImpl.h + * test/XmlRpcMethodTest.cc + 2009-06-24 Tatsuhiro Tsujikawa Updated CookieStorageTest diff --git a/src/SingleFileDownloadContext.cc b/src/SingleFileDownloadContext.cc index 92332f85..1acbb2b1 100644 --- a/src/SingleFileDownloadContext.cc +++ b/src/SingleFileDownloadContext.cc @@ -83,7 +83,11 @@ bool SingleFileDownloadContext::knowsTotalLength() const size_t SingleFileDownloadContext::getNumPieces() const { - return (_fileEntries.front()->getLength()+_pieceLength-1)/_pieceLength; + if(_pieceLength == 0) { + return 0; + } else { + return (_fileEntries.front()->getLength()+_pieceLength-1)/_pieceLength; + } } std::string SingleFileDownloadContext::getActualBasePath() const diff --git a/src/XmlRpcMethodFactory.cc b/src/XmlRpcMethodFactory.cc index c42007ab..f6495fc8 100644 --- a/src/XmlRpcMethodFactory.cc +++ b/src/XmlRpcMethodFactory.cc @@ -71,6 +71,8 @@ XmlRpcMethodFactory::create(const std::string& methodName) #endif // ENABLE_BITTORRENT } else if(methodName == "aria2.tellActive") { return SharedHandle(new TellActiveXmlRpcMethod()); + } else if(methodName == "aria2.tellWaiting") { + return SharedHandle(new TellWaitingXmlRpcMethod()); } else if(methodName == "aria2.changeOption") { return SharedHandle(new ChangeOptionXmlRpcMethod()); } else if(methodName == "aria2.changeGlobalOption") { diff --git a/src/XmlRpcMethodImpl.cc b/src/XmlRpcMethodImpl.cc index 176f18c0..8bc629a2 100644 --- a/src/XmlRpcMethodImpl.cc +++ b/src/XmlRpcMethodImpl.cc @@ -521,6 +521,48 @@ BDE TellActiveXmlRpcMethod::process return list; } +BDE TellWaitingXmlRpcMethod::process +(const XmlRpcRequest& req, DownloadEngine* e) +{ + const BDE& params = req._params; + assert(params.isList()); + + if(params.size() != 2 || + !params[0].isInteger() || !params[1].isInteger() || + params[0].i() < 0 || params[1].i() < 0) { + throw DL_ABORT_EX("Invalid argument. Specify offset and num in integer."); + } + + size_t offset = params[0].i(); + size_t num = params[1].i(); + + BDE list = BDE::list(); + const std::deque >& waitings = + e->_requestGroupMan->getReservedGroups(); + if(waitings.size() <= offset) { + return list; + } + size_t lastDistance; + if(waitings.size() < offset+num) { + lastDistance = waitings.size(); + } else { + lastDistance = offset+num; + } + std::deque >::const_iterator first = + waitings.begin(); + std::advance(first, offset); + std::deque >::const_iterator last = + waitings.begin(); + std::advance(last, lastDistance); + for(; first != last; ++first) { + BDE entryDict = BDE::dict(); + entryDict["status"] = BDE_WAITING; + gatherProgress(entryDict, *first, e); + list << entryDict; + } + return list; +} + BDE PurgeDownloadResultXmlRpcMethod::process (const XmlRpcRequest& req, DownloadEngine* e) { diff --git a/src/XmlRpcMethodImpl.h b/src/XmlRpcMethodImpl.h index 917b198d..765f7748 100644 --- a/src/XmlRpcMethodImpl.h +++ b/src/XmlRpcMethodImpl.h @@ -97,6 +97,11 @@ protected: virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); }; +class TellWaitingXmlRpcMethod:public XmlRpcMethod { +protected: + virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); +}; + class ChangeOptionXmlRpcMethod:public XmlRpcMethod { protected: virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); diff --git a/test/XmlRpcMethodTest.cc b/test/XmlRpcMethodTest.cc index 41f02f5b..cfc763b2 100644 --- a/test/XmlRpcMethodTest.cc +++ b/test/XmlRpcMethodTest.cc @@ -49,6 +49,8 @@ class XmlRpcMethodTest:public CppUnit::TestFixture { CPPUNIT_TEST(testChangeGlobalOption); CPPUNIT_TEST(testChangeGlobalOption_withBadOption); CPPUNIT_TEST(testTellStatus_withoutGid); + CPPUNIT_TEST(testTellWaiting); + CPPUNIT_TEST(testTellWaiting_fail); CPPUNIT_TEST(testNoSuchMethod); CPPUNIT_TEST_SUITE_END(); private: @@ -60,6 +62,7 @@ public: RequestGroup::resetGIDCounter(); _option.reset(new Option()); _option->put(PREF_DIR, "/tmp"); + _option->put(PREF_SEGMENT_SIZE, "1048576"); _e.reset(new DownloadEngine(SharedHandle(new SelectEventPoll()))); _e->option = _option.get(); _e->_requestGroupMan.reset @@ -93,6 +96,8 @@ public: void testChangeGlobalOption(); void testChangeGlobalOption_withBadOption(); void testTellStatus_withoutGid(); + void testTellWaiting(); + void testTellWaiting_fail(); void testNoSuchMethod(); }; @@ -461,6 +466,56 @@ void XmlRpcMethodTest::testTellStatus_withoutGid() CPPUNIT_ASSERT_EQUAL(1, res._code); } +static void addUri(const std::string& uri, + const SharedHandle& e) +{ + AddUriXmlRpcMethod m; + XmlRpcRequest req("aria2.addUri", BDE::list()); + req._params << BDE::list(); + req._params[0] << BDE(uri); + CPPUNIT_ASSERT_EQUAL(0, m.execute(req, e.get())._code); +} + +void XmlRpcMethodTest::testTellWaiting() +{ + addUri("http://1/", _e); + addUri("http://2/", _e); + addUri("http://3/", _e); + addUri("http://4/", _e); + + TellWaitingXmlRpcMethod m; + XmlRpcRequest req("aria2.tellWaiting", BDE::list()); + req._params << BDE((int64_t)1); + req._params << BDE((int64_t)2); + XmlRpcResponse res = m.execute(req, _e.get()); + CPPUNIT_ASSERT_EQUAL(0, res._code); + CPPUNIT_ASSERT_EQUAL((size_t)2, res._param.size()); + CPPUNIT_ASSERT_EQUAL(std::string("2"), res._param[0]["gid"].s()); + CPPUNIT_ASSERT_EQUAL(std::string("3"), res._param[1]["gid"].s()); + // waiting.size() == offset+num + req = XmlRpcRequest("aria2.tellWaiting", BDE::list()); + req._params << BDE((int64_t)1); + req._params << BDE((int64_t)3); + res = m.execute(req, _e.get()); + CPPUNIT_ASSERT_EQUAL(0, res._code); + CPPUNIT_ASSERT_EQUAL((size_t)3, res._param.size()); + // waiting.size() < offset+num + req = XmlRpcRequest("aria2.tellWaiting", BDE::list()); + req._params << BDE((int64_t)1); + req._params << BDE((int64_t)4); + res = m.execute(req, _e.get()); + CPPUNIT_ASSERT_EQUAL(0, res._code); + CPPUNIT_ASSERT_EQUAL((size_t)3, res._param.size()); +} + +void XmlRpcMethodTest::testTellWaiting_fail() +{ + TellWaitingXmlRpcMethod m; + XmlRpcRequest req("aria2.tellWaiting", BDE::list()); + XmlRpcResponse res = m.execute(req, _e.get()); + CPPUNIT_ASSERT_EQUAL(1, res._code); +} + } // namespace xmlrpc } // namespace aria2