2010-01-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Now offset argument in aria2.tellWaiting and aria2.tellStopped
	accepts a negative integer.  'offset' == -1 points last download
	in the waiting queue and 'offset' == -2 points the download before
	the last download, and so on. The downloads in the response are in
	reversed order.
	* doc/aria2c.1.txt
	* src/XmlRpcMethodImpl.cc
	* src/XmlRpcMethodImpl.h
	* test/XmlRpcMethodTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-01-17 09:50:38 +00:00
parent c0308e1ea4
commit f9c6c0ccd8
7 changed files with 228 additions and 93 deletions

View File

@ -1,3 +1,15 @@
2010-01-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Now offset argument in aria2.tellWaiting and aria2.tellStopped
accepts a negative integer. 'offset' == -1 points last download
in the waiting queue and 'offset' == -2 points the download before
the last download, and so on. The downloads in the response are in
reversed order.
* doc/aria2c.1.txt
* src/XmlRpcMethodImpl.cc
* src/XmlRpcMethodImpl.h
* test/XmlRpcMethodTest.cc
2010-01-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added --human-readable option. This option, when true is given,

View File

@ -2376,15 +2376,27 @@ seeder
.sp
\fBaria2\&.tellActive\fR
.sp
This method returns the list of active downloads\&. The respose is of type array and its element is the same struct returned by \fBaria2\&.tellStatus\fR method\&.
This method returns the list of active downloads\&. The response is of type array and its element is the same struct returned by \fBaria2\&.tellStatus\fR method\&.
.sp
\fBaria2\&.tellWaiting\fR \fIoffset, num\fR
.sp
This method returns the list of waiting download in the range of [\fIoffset\fR, \fIoffset\fR+\fInum\fR)\&. \fIoffset\fR is of type integer and specifies the offset from the download waiting at the front\&. \fInum\fR is of type integer and specifies the number of downloads to be returned\&. For example, imagine that three downloads "A","B" and "C" are waiting in this order\&. aria2\&.tellWaiting(0, 1) returns "A"\&. aria2\&.tellWaiting(1, 2) returns "B" and "C"\&. The respose is of type array and its element is the same struct returned by \fBaria2\&.tellStatus\fR method\&.
This method returns the list of waiting download\&. \fIoffset\fR is of type integer and specifies the offset from the download waiting at the front\&. \fInum\fR is of type integer and specifies the number of downloads to be returned\&.
.sp
If offset is a positive integer, this method returns downloads in the range of [\fIoffset\fR, \fIoffset\fR+\fInum\fR)\&.
.sp
\fIoffset\fR can be a negative integer\&. \fIoffset\fR == \-1 points last download in the waiting queue and \fIoffset\fR == \-2 points the download before the last download, and so on\&. The downloads in the response are in reversed order\&.
.sp
For example, imagine that three downloads "A","B" and "C" are waiting in this order\&. aria2\&.tellWaiting(0, 1) returns ["A"]\&. aria2\&.tellWaiting(1, 2) returns ["B", "C"]\&. aria2\&.tellWaiting(\-1, 2) returns ["C", "B"]\&.
.sp
The response is of type array and its element is the same struct returned by \fBaria2\&.tellStatus\fR method\&.
.sp
\fBaria2\&.tellStopped\fR \fIoffset, num\fR
.sp
This method returns the list of stopped download in the range of [\fIoffset\fR, \fIoffset\fR+\fInum\fR)\&. \fIoffset\fR is of type integer and specifies the offset from the oldest download\&. \fInum\fR is of type integer and specifies the number of downloads to be returned\&. The respose is of type array and its element is the same struct returned by \fBaria2\&.tellStatus\fR method\&.
This method returns the list of stopped download\&. \fIoffset\fR is of type integer and specifies the offset from the oldest download\&. \fInum\fR is of type integer and specifies the number of downloads to be returned\&.
.sp
\fIoffset\fR and \fInum\fR have the same semantics as \fBaria2\&.tellWaiting\fR method\&.
.sp
The response is of type array and its element is the same struct returned by \fBaria2\&.tellStatus\fR method\&.
.sp
\fBaria2\&.changePosition\fR \fIgid, pos, how\fR
.sp

View File

@ -3031,25 +3031,34 @@ seeder
</dd>
</dl></div>
<div class="paragraph"><p><strong>aria2.tellActive</strong></p></div>
<div class="paragraph"><p>This method returns the list of active downloads. The respose is of
<div class="paragraph"><p>This method returns the list of active downloads. The response is of
type array and its element is the same struct returned by
<strong>aria2.tellStatus</strong> method.</p></div>
<div class="paragraph"><p><strong>aria2.tellWaiting</strong> <em>offset, num</em></p></div>
<div class="paragraph"><p>This method returns the list of waiting download in the range of
[<em>offset</em>, <em>offset</em>+<em>num</em>). <em>offset</em> is of type integer and specifies
the offset from the download waiting at the front. <em>num</em> is of type
integer and specifies the number of downloads to be returned. For
example, imagine that three downloads "A","B" and "C" are waiting in
this order. aria2.tellWaiting(0, 1) returns "A". aria2.tellWaiting(1,
2) returns "B" and "C". The respose is of type array and its element
is the same struct returned by <strong>aria2.tellStatus</strong> method.</p></div>
<div class="paragraph"><p>This method returns the list of waiting download. <em>offset</em> is of type
integer and specifies the offset from the download waiting at the
front. <em>num</em> is of type integer and specifies the number of downloads
to be returned.</p></div>
<div class="paragraph"><p>If offset is a positive integer, this method returns downloads in the
range of [<em>offset</em>, <em>offset</em>+<em>num</em>).</p></div>
<div class="paragraph"><p><em>offset</em> can be a negative integer. <em>offset</em> == -1 points last
download in the waiting queue and <em>offset</em> == -2 points the download
before the last download, and so on. The downloads in the response are
in reversed order.</p></div>
<div class="paragraph"><p>For example, imagine that three downloads "A","B" and "C" are waiting
in this order. aria2.tellWaiting(0, 1) returns
["A"]. aria2.tellWaiting(1, 2) returns ["B", "C"].
aria2.tellWaiting(-1, 2) returns ["C", "B"].</p></div>
<div class="paragraph"><p>The response is of type array and its element is the same struct
returned by <strong>aria2.tellStatus</strong> method.</p></div>
<div class="paragraph"><p><strong>aria2.tellStopped</strong> <em>offset, num</em></p></div>
<div class="paragraph"><p>This method returns the list of stopped download in the range of
[<em>offset</em>, <em>offset</em>+<em>num</em>). <em>offset</em> is of type integer and specifies
the offset from the oldest download. <em>num</em> is of type integer and
specifies the number of downloads to be returned. The respose is of
type array and its element is the same struct returned by
<strong>aria2.tellStatus</strong> method.</p></div>
<div class="paragraph"><p>This method returns the list of stopped download. <em>offset</em> is of type
integer and specifies the offset from the oldest download. <em>num</em> is of
type integer and specifies the number of downloads to be returned.</p></div>
<div class="paragraph"><p><em>offset</em> and <em>num</em> have the same semantics as <strong>aria2.tellWaiting</strong>
method.</p></div>
<div class="paragraph"><p>The response is of type array and its element is the same struct
returned by <strong>aria2.tellStatus</strong> method.</p></div>
<div class="paragraph"><p><strong>aria2.changePosition</strong> <em>gid, pos, how</em></p></div>
<div class="paragraph"><p>This method changes the position of the download denoted by
<em>gid</em>. <em>pos</em> is of type integer. <em>how</em> is of type string. If <em>how</em> is
@ -3587,7 +3596,7 @@ files in the program, then also delete it here.</p></div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2010-01-17 16:21:53 JST
Last updated 2010-01-17 18:47:03 JST
</div>
</div>
</body>

View File

@ -1352,29 +1352,44 @@ seeder::
*aria2.tellActive*
This method returns the list of active downloads. The respose is of
This method returns the list of active downloads. The response is of
type array and its element is the same struct returned by
*aria2.tellStatus* method.
*aria2.tellWaiting* 'offset, num'
This method returns the list of waiting download in the range of
['offset', 'offset'+'num'). 'offset' is of type integer and specifies
the offset from the download waiting at the front. 'num' is of type
integer and specifies the number of downloads to be returned. For
example, imagine that three downloads "A","B" and "C" are waiting in
this order. aria2.tellWaiting(0, 1) returns "A". aria2.tellWaiting(1,
2) returns "B" and "C". The respose is of type array and its element
is the same struct returned by *aria2.tellStatus* method.
This method returns the list of waiting download. 'offset' is of type
integer and specifies the offset from the download waiting at the
front. 'num' is of type integer and specifies the number of downloads
to be returned.
If offset is a positive integer, this method returns downloads in the
range of ['offset', 'offset'+'num').
'offset' can be a negative integer. 'offset' == -1 points last
download in the waiting queue and 'offset' == -2 points the download
before the last download, and so on. The downloads in the response are
in reversed order.
For example, imagine that three downloads "A","B" and "C" are waiting
in this order. aria2.tellWaiting(0, 1) returns
["A"]. aria2.tellWaiting(1, 2) returns ["B", "C"].
aria2.tellWaiting(-1, 2) returns ["C", "B"].
The response is of type array and its element is the same struct
returned by *aria2.tellStatus* method.
*aria2.tellStopped* 'offset, num'
This method returns the list of stopped download in the range of
['offset', 'offset'+'num'). 'offset' is of type integer and specifies
the offset from the oldest download. 'num' is of type integer and
specifies the number of downloads to be returned. The respose is of
type array and its element is the same struct returned by
*aria2.tellStatus* method.
This method returns the list of stopped download. 'offset' is of type
integer and specifies the offset from the oldest download. 'num' is of
type integer and specifies the number of downloads to be returned.
'offset' and 'num' have the same semantics as *aria2.tellWaiting*
method.
The response is of type array and its element is the same struct
returned by *aria2.tellStatus* method.
*aria2.changePosition* 'gid, pos, how'

View File

@ -586,73 +586,43 @@ BDE TellActiveXmlRpcMethod::process
return list;
}
template<typename InputIterator>
static std::pair<InputIterator, InputIterator>
getPaginationRange
(const XmlRpcRequest& req, InputIterator first, InputIterator last)
template<typename T>
void AbstractPaginationXmlRpcMethod<T>::checkPaginationParams
(const BDE& params) const
{
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) {
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();
size_t size = std::distance(first, last);
if(size <= offset) {
return std::make_pair(last, last);
}
size_t lastDistance;
if(size < offset+num) {
lastDistance = size;
} else {
lastDistance = offset+num;
}
last = first;
std::advance(first, offset);
std::advance(last, lastDistance);
return std::make_pair(first, last);
}
BDE TellWaitingXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
const std::deque<SharedHandle<RequestGroup> >&
TellWaitingXmlRpcMethod::getItems(DownloadEngine* e) const
{
const std::deque<SharedHandle<RequestGroup> >& waitings =
e->_requestGroupMan->getReservedGroups();
std::pair<std::deque<SharedHandle<RequestGroup> >::const_iterator,
std::deque<SharedHandle<RequestGroup> >::const_iterator> range =
getPaginationRange(req, waitings.begin(), waitings.end());
BDE list = BDE::list();
for(; range.first != range.second; ++range.first) {
BDE entryDict = BDE::dict();
entryDict[KEY_STATUS] = BDE_WAITING;
gatherProgress(entryDict, *range.first, e);
list << entryDict;
}
return list;
return e->_requestGroupMan->getReservedGroups();
}
BDE TellStoppedXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
void TellWaitingXmlRpcMethod::createEntry
(BDE& entryDict, const SharedHandle<RequestGroup>& item,
DownloadEngine* e) const
{
const std::deque<SharedHandle<DownloadResult> >& stopped =
e->_requestGroupMan->getDownloadResults();
std::pair<std::deque<SharedHandle<DownloadResult> >::const_iterator,
std::deque<SharedHandle<DownloadResult> >::const_iterator> range =
getPaginationRange(req, stopped.begin(), stopped.end());
BDE list = BDE::list();
for(; range.first != range.second; ++range.first) {
BDE entryDict = BDE::dict();
gatherStoppedDownload(entryDict, *range.first);
list << entryDict;
}
return list;
entryDict[KEY_STATUS] = BDE_WAITING;
gatherProgress(entryDict, item, e);
}
const std::deque<SharedHandle<DownloadResult> >&
TellStoppedXmlRpcMethod::getItems(DownloadEngine* e) const
{
return e->_requestGroupMan->getDownloadResults();
}
void TellStoppedXmlRpcMethod::createEntry
(BDE& entryDict, const SharedHandle<DownloadResult>& item,
DownloadEngine* e) const
{
gatherStoppedDownload(entryDict, item);
}
BDE PurgeDownloadResultXmlRpcMethod::process

View File

@ -37,6 +37,12 @@
#include "XmlRpcMethod.h"
#include <deque>
#include <algorithm>
#include "BDE.h"
#include "XmlRpcRequest.h"
namespace aria2 {
class DownloadResult;
@ -160,9 +166,81 @@ public:
}
};
class TellWaitingXmlRpcMethod:public XmlRpcMethod {
template<typename T>
class AbstractPaginationXmlRpcMethod:public XmlRpcMethod {
private:
template<typename InputIterator>
std::pair<InputIterator, InputIterator>
getPaginationRange
(ssize_t offset, size_t num, InputIterator first, InputIterator last)
{
size_t size = std::distance(first, last);
if(offset < 0) {
ssize_t tempoffset = offset+size;
if(tempoffset < 0) {
return std::make_pair(last, last);
}
offset = tempoffset-(num-1);
if(offset < 0) {
offset = 0;
num = tempoffset+1;
}
} else if(size <= (size_t)offset) {
return std::make_pair(last, last);
}
BDE list = BDE::list();
size_t lastDistance;
if(size < offset+num) {
lastDistance = size;
} else {
lastDistance = offset+num;
}
last = first;
std::advance(first, offset);
std::advance(last, lastDistance);
return std::make_pair(first, last);
}
void checkPaginationParams(const BDE& params) const;
protected:
virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e)
{
const BDE& params = req._params;
checkPaginationParams(params);
ssize_t offset = params[0].i();
size_t num = params[1].i();
const std::deque<SharedHandle<T> >& items = getItems(e);
std::pair<typename std::deque<SharedHandle<T> >::const_iterator,
typename std::deque<SharedHandle<T> >::const_iterator> range =
getPaginationRange(offset, num, items.begin(), items.end());
BDE list = BDE::list();
for(; range.first != range.second; ++range.first) {
BDE entryDict = BDE::dict();
createEntry(entryDict, *range.first, e);
list << entryDict;
}
if(offset < 0) {
std::reverse(list.listBegin(), list.listEnd());
}
return list;
}
virtual const std::deque<SharedHandle<T> >&
getItems(DownloadEngine* e) const = 0;
virtual void createEntry
(BDE& entryDict, const SharedHandle<T>& item, DownloadEngine* e) const = 0;
};
class TellWaitingXmlRpcMethod:
public AbstractPaginationXmlRpcMethod<RequestGroup> {
protected:
virtual const std::deque<SharedHandle<RequestGroup> >&
getItems(DownloadEngine* e) const;
virtual void createEntry
(BDE& entryDict, const SharedHandle<RequestGroup>& item,
DownloadEngine* e) const;
public:
static const std::string& getMethodName()
{
@ -171,9 +249,15 @@ public:
}
};
class TellStoppedXmlRpcMethod:public XmlRpcMethod {
class TellStoppedXmlRpcMethod:
public AbstractPaginationXmlRpcMethod<DownloadResult> {
protected:
virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
virtual const std::deque<SharedHandle<DownloadResult> >&
getItems(DownloadEngine* e) const;
virtual void createEntry
(BDE& entryDict, const SharedHandle<DownloadResult>& item,
DownloadEngine* e) const;
public:
static const std::string& getMethodName()
{

View File

@ -608,6 +608,39 @@ void XmlRpcMethodTest::testTellWaiting()
#else //!ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL((size_t)2, res._param.size());
#endif // !ENABLE_BITTORRENT
// negative offset
req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), BDE::list());
req._params << BDE((int64_t)-1);
req._params << BDE((int64_t)2);
res = m.execute(req, _e.get());
CPPUNIT_ASSERT_EQUAL(0, res._code);
CPPUNIT_ASSERT_EQUAL((size_t)2, res._param.size());
#ifdef ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL(std::string("4"), res._param[0]["gid"].s());
CPPUNIT_ASSERT_EQUAL(std::string("3"), res._param[1]["gid"].s());
#else // !ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL(std::string("3"), res._param[0]["gid"].s());
CPPUNIT_ASSERT_EQUAL(std::string("2"), res._param[1]["gid"].s());
#endif // !ENABLE_BITTORRENT
// negative offset and size < num
req._params[1] = BDE((int64_t)100);
res = m.execute(req, _e.get());
CPPUNIT_ASSERT_EQUAL(0, res._code);
#ifdef ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL((size_t)4, res._param.size());
#else // !ENABLE_BITTORRENT
CPPUNIT_ASSERT_EQUAL((size_t)3, res._param.size());
#endif // !ENABLE_BITTORRENT
// nagative offset and normalized offset < 0
req._params[0] = BDE((int64_t)-5);
res = m.execute(req, _e.get());
CPPUNIT_ASSERT_EQUAL(0, res._code);
CPPUNIT_ASSERT_EQUAL((size_t)0, res._param.size());
// nagative offset and normalized offset == 0
req._params[0] = BDE((int64_t)-4);
res = m.execute(req, _e.get());
CPPUNIT_ASSERT_EQUAL(0, res._code);
CPPUNIT_ASSERT_EQUAL((size_t)1, res._param.size());
}
void XmlRpcMethodTest::testTellWaiting_fail()