소스 검색

2009-12-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Added changePosition XML-RPC method. It takes 3 parameters: gid,
	pos and how.  This method changes the position of download denoted
	by gid.  If how is POS_SET, it moves the download to a position
	relative to the beginning of the queue.  If how is POS_CUR, it
	moves the download to a position relative to the current
	position. If how is POS_END, it moves the download to a position
	relative to the end of the queue. If the destination position is
	less than 0 or beyond the end of the queue, it moves the download
	to the beginning or the end of the queue respectively.  Returns
	the destination position.
	* src/RequestGroupMan.cc
	* src/RequestGroupMan.h
	* src/XmlRpcMethodFactory.cc
	* src/XmlRpcMethodImpl.cc
	* src/XmlRpcMethodImpl.h
	* test/RequestGroupManTest.cc
	* test/XmlRpcMethodTest.cc
Tatsuhiro Tsujikawa 16 년 전
부모
커밋
dd98c64161
8개의 변경된 파일210개의 추가작업 그리고 0개의 파일을 삭제
  1. 20 0
      ChangeLog
  2. 43 0
      src/RequestGroupMan.cc
  3. 17 0
      src/RequestGroupMan.h
  4. 2 0
      src/XmlRpcMethodFactory.cc
  5. 29 0
      src/XmlRpcMethodImpl.cc
  6. 5 0
      src/XmlRpcMethodImpl.h
  7. 58 0
      test/RequestGroupManTest.cc
  8. 36 0
      test/XmlRpcMethodTest.cc

+ 20 - 0
ChangeLog

@@ -1,3 +1,23 @@
+2009-12-22  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Added changePosition XML-RPC method. It takes 3 parameters: gid,
+	pos and how.  This method changes the position of download denoted
+	by gid.  If how is POS_SET, it moves the download to a position
+	relative to the beginning of the queue.  If how is POS_CUR, it
+	moves the download to a position relative to the current
+	position. If how is POS_END, it moves the download to a position
+	relative to the end of the queue. If the destination position is
+	less than 0 or beyond the end of the queue, it moves the download
+	to the beginning or the end of the queue respectively.  Returns
+	the destination position.
+	* src/RequestGroupMan.cc
+	* src/RequestGroupMan.h
+	* src/XmlRpcMethodFactory.cc
+	* src/XmlRpcMethodImpl.cc
+	* src/XmlRpcMethodImpl.h
+	* test/RequestGroupManTest.cc
+	* test/XmlRpcMethodTest.cc
+
 2009-12-20  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Added getOption and getGlobalOption to aria2rpc.

+ 43 - 0
src/RequestGroupMan.cc

@@ -66,6 +66,7 @@
 #include "util.h"
 #include "Command.h"
 #include "FileEntry.h"
+#include "StringFormat.h"
 
 namespace aria2 {
 
@@ -173,6 +174,48 @@ RequestGroupMan::findReservedGroup(int32_t gid) const
   }
 }
 
+size_t RequestGroupMan::changeReservedGroupPosition
+(int32_t gid, int pos, HOW how)
+{
+  std::deque<SharedHandle<RequestGroup> >::iterator i =
+    findByGID(_reservedGroups.begin(), _reservedGroups.end(), gid);
+  if(i == _reservedGroups.end()) {
+    throw DL_ABORT_EX
+      (StringFormat("GID#%d not found in the waiting queue.", gid).str());
+  }
+  SharedHandle<RequestGroup> rg = *i;
+  if(how == POS_SET) {
+    _reservedGroups.erase(i);
+    if(pos < 0) {
+      pos = 0;
+    } else if(pos > 0) {
+      pos = std::min(_reservedGroups.size(), (size_t)pos);
+    }
+  } else if(how == POS_CUR) {
+    size_t abspos = std::distance(_reservedGroups.begin(), i);
+    if(pos < 0) {
+      int dist = -std::distance(_reservedGroups.begin(), i);
+      pos = abspos+std::max(pos, dist);
+    } else if(pos > 0) {
+      int dist = std::distance(i, _reservedGroups.end())-1;
+      pos = abspos+std::min(pos, dist);
+    } else {
+      pos = abspos;
+    }
+    _reservedGroups.erase(i);
+  } else if(how == POS_END) {
+    _reservedGroups.erase(i);
+    if(pos >= 0) {
+      pos = _reservedGroups.size();
+    } else {
+      pos =
+	_reservedGroups.size()-std::min(_reservedGroups.size(), (size_t)-pos);
+    }
+  }
+  _reservedGroups.insert(_reservedGroups.begin()+pos, rg);
+  return pos;
+}
+
 bool RequestGroupMan::removeReservedGroup(int32_t gid)
 {
   std::deque<SharedHandle<RequestGroup> >::iterator i =

+ 17 - 0
src/RequestGroupMan.h

@@ -130,6 +130,23 @@ public:
 
   SharedHandle<RequestGroup> findReservedGroup(int32_t gid) const;
 
+  enum HOW {
+    POS_SET,
+    POS_CUR,
+    POS_END
+  };
+
+  // Changes the position of download denoted by gid.  If how is
+  // POS_SET, it moves the download to a position relative to the
+  // beginning of the queue.  If how is POS_CUR, it moves the download
+  // to a position relative to the current position. If how is
+  // POS_END, it moves the download to a position relative to the end
+  // of the queue. If the destination position is less than 0 or
+  // beyond the end of the queue, it moves the download to the
+  // beginning or the end of the queue respectively.  Returns the
+  // destination position.
+  size_t changeReservedGroupPosition(int32_t gid, int pos, HOW how);
+
   bool removeReservedGroup(int32_t gid);
 
   void showDownloadResults(std::ostream& o) const;

+ 2 - 0
src/XmlRpcMethodFactory.cc

@@ -58,6 +58,8 @@ XmlRpcMethodFactory::create(const std::string& methodName)
   }
   else if(methodName == "aria2.remove") {
     return SharedHandle<XmlRpcMethod>(new RemoveXmlRpcMethod());
+  } else if(methodName == "aria2.changePosition") {
+    return SharedHandle<XmlRpcMethod>(new ChangePositionXmlRpcMethod());
   } else if(methodName == "aria2.tellStatus") {
     return SharedHandle<XmlRpcMethod>(new TellStatusXmlRpcMethod());
   } else if(methodName == "aria2.getUris") {

+ 29 - 0
src/XmlRpcMethodImpl.cc

@@ -727,6 +727,35 @@ BDE GetGlobalOptionXmlRpcMethod::process
   return result;
 }
 
+BDE ChangePositionXmlRpcMethod::process
+(const XmlRpcRequest& req, DownloadEngine* e)
+{
+  const BDE& params = req._params;
+  assert(params.isList());
+
+  if(params.size() != 3 ||
+     !params[0].isString() || !params[1].isInteger() || !params[2].isString()) {
+    throw DL_ABORT_EX("Illegal argument.");
+  }
+  int32_t gid = util::parseInt(params[0].s());
+  int pos = params[1].i();
+  const std::string& howStr = params[2].s();
+  RequestGroupMan::HOW how;
+  if(howStr == "POS_SET") {
+    how = RequestGroupMan::POS_SET;
+  } else if(howStr == "POS_CUR") {
+    how = RequestGroupMan::POS_CUR;
+  } else if(howStr == "POS_END") {
+    how = RequestGroupMan::POS_END;
+  } else {
+    throw DL_ABORT_EX("Illegal argument.");
+  }
+  size_t destPos =
+    e->_requestGroupMan->changeReservedGroupPosition(gid, pos, how);
+  BDE result(destPos);
+  return result;
+}
+
 BDE NoSuchMethodXmlRpcMethod::process
 (const XmlRpcRequest& req, DownloadEngine* e)
 {

+ 5 - 0
src/XmlRpcMethodImpl.h

@@ -130,6 +130,11 @@ protected:
   virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
 };
 
+class ChangePositionXmlRpcMethod:public XmlRpcMethod {
+protected:
+  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+};
+
 class NoSuchMethodXmlRpcMethod:public XmlRpcMethod {
 protected:
   virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);

+ 58 - 0
test/RequestGroupManTest.cc

@@ -13,6 +13,7 @@
 #include "ServerStatMan.h"
 #include "ServerStat.h"
 #include "File.h"
+#include "array_fun.h"
 
 namespace aria2 {
 
@@ -23,12 +24,14 @@ class RequestGroupManTest : public CppUnit::TestFixture {
   CPPUNIT_TEST(testGetInitialCommands);
   CPPUNIT_TEST(testLoadServerStat);
   CPPUNIT_TEST(testSaveServerStat);
+  CPPUNIT_TEST(testChangeReservedGroupPosition);
   CPPUNIT_TEST_SUITE_END();
 private:
   SharedHandle<Option> _option;
 public:
   void setUp()
   {
+    RequestGroup::resetGIDCounter();
     _option.reset(new Option());
   }
 
@@ -36,6 +39,7 @@ public:
   void testGetInitialCommands();
   void testLoadServerStat();
   void testSaveServerStat();
+  void testChangeReservedGroupPosition();
 };
 
 
@@ -107,4 +111,58 @@ void RequestGroupManTest::testLoadServerStat()
   CPPUNIT_ASSERT_EQUAL(std::string("localhost"), ss_localhost->getHostname());
 }
 
+void RequestGroupManTest::testChangeReservedGroupPosition()
+{
+  SharedHandle<RequestGroup> gs[] = {
+    SharedHandle<RequestGroup>(new RequestGroup(_option)),
+    SharedHandle<RequestGroup>(new RequestGroup(_option)),
+    SharedHandle<RequestGroup>(new RequestGroup(_option)),
+    SharedHandle<RequestGroup>(new RequestGroup(_option))
+  };
+  std::deque<SharedHandle<RequestGroup> > groups(&gs[0], &gs[arrayLength(gs)]);
+  RequestGroupMan rm(groups, 0, _option.get());
+
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)0, rm.changeReservedGroupPosition(1, 0, RequestGroupMan::POS_SET));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)1, rm.changeReservedGroupPosition(1, 1, RequestGroupMan::POS_SET));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)3, rm.changeReservedGroupPosition(1, 10,RequestGroupMan::POS_SET));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)0, rm.changeReservedGroupPosition(1,-10,RequestGroupMan::POS_SET));
+  
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)1, rm.changeReservedGroupPosition(2, 0, RequestGroupMan::POS_CUR));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)2, rm.changeReservedGroupPosition(2, 1, RequestGroupMan::POS_CUR));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)1, rm.changeReservedGroupPosition(2, -1,RequestGroupMan::POS_CUR));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)0, rm.changeReservedGroupPosition(2,-10,RequestGroupMan::POS_CUR));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)1, rm.changeReservedGroupPosition(2, 1, RequestGroupMan::POS_CUR));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)3, rm.changeReservedGroupPosition(2, 10,RequestGroupMan::POS_CUR));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)1, rm.changeReservedGroupPosition(2, -2,RequestGroupMan::POS_CUR));
+
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)3, rm.changeReservedGroupPosition(4, 0, RequestGroupMan::POS_END));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)2, rm.changeReservedGroupPosition(4, -1,RequestGroupMan::POS_END));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)0, rm.changeReservedGroupPosition(4,-10,RequestGroupMan::POS_END));
+  CPPUNIT_ASSERT_EQUAL
+    ((size_t)3, rm.changeReservedGroupPosition(4, 10,RequestGroupMan::POS_END));
+
+  CPPUNIT_ASSERT_EQUAL((size_t)4, rm.getReservedGroups().size());
+
+  try {
+    rm.changeReservedGroupPosition(5, 0, RequestGroupMan::POS_CUR);
+    CPPUNIT_FAIL("exception must be thrown.");
+  } catch(RecoverableException& e) {
+    // success
+  }
+}
+
 } // namespace aria2

+ 36 - 0
test/XmlRpcMethodTest.cc

@@ -67,6 +67,8 @@ class XmlRpcMethodTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testNoSuchMethod);
   CPPUNIT_TEST(testGatherStoppedDownload);
   CPPUNIT_TEST(testGatherProgressCommon);
+  CPPUNIT_TEST(testChangePosition);
+  CPPUNIT_TEST(testChangePosition_fail);
   CPPUNIT_TEST_SUITE_END();
 private:
   SharedHandle<DownloadEngine> _e;
@@ -119,6 +121,8 @@ public:
   void testNoSuchMethod();
   void testGatherStoppedDownload();
   void testGatherProgressCommon();
+  void testChangePosition();
+  void testChangePosition_fail();
 };
 
 
@@ -676,6 +680,38 @@ void XmlRpcMethodTest::testGatherProgressCommon()
   CPPUNIT_ASSERT_EQUAL(std::string("2"), entry["belongsTo"].s());
 }
 
+void XmlRpcMethodTest::testChangePosition()
+{
+  _e->_requestGroupMan->addReservedGroup
+    (SharedHandle<RequestGroup>(new RequestGroup(_option)));
+  _e->_requestGroupMan->addReservedGroup
+    (SharedHandle<RequestGroup>(new RequestGroup(_option)));
+
+  ChangePositionXmlRpcMethod m;
+  XmlRpcRequest req("aria2.changePosition", BDE::list());
+  req._params << std::string("1");
+  req._params << BDE((int64_t)1);
+  req._params << std::string("POS_SET");
+  XmlRpcResponse res = m.execute(req, _e.get());
+  CPPUNIT_ASSERT_EQUAL(0, res._code);
+  CPPUNIT_ASSERT_EQUAL((int64_t)1, res._param.i());
+  CPPUNIT_ASSERT_EQUAL
+    ((int32_t)1, _e->_requestGroupMan->getReservedGroups()[1]->getGID());
+}
+
+void XmlRpcMethodTest::testChangePosition_fail()
+{
+  ChangePositionXmlRpcMethod m;
+  XmlRpcRequest req("aria2.changePosition", BDE::list());
+  XmlRpcResponse res = m.execute(req, _e.get());
+  CPPUNIT_ASSERT_EQUAL(1, res._code);
+
+  req._params << std::string("1");
+  req._params << BDE((int64_t)2);
+  req._params << std::string("bad keyword");
+  CPPUNIT_ASSERT_EQUAL(1, res._code);
+}
+
 } // namespace xmlrpc
 
 } // namespace aria2