2010-09-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Added keys parameter to aria2.tellStatus, aria2.tellActive,
	aria2.tellWaiting and aria2.tellStopped XML-RPC method.  'keys' is
	array of string. If it is specified, the response contains only
	keys in 'keys' array. If 'keys' is empty or not specified, the
	response contains all keys.  This is useful when you just want
	specific keys and avoid unnecessary transfers. For example,
	*aria2.tellStatus*("1", ["gid", "status"]) returns 'gid' and
	'status' key. Made get*Param() functions XmlRpcRequest's
	methods and changed portions of the code that were affected by
	this change.
	* doc/aria2c.1.txt
	* src/Makefile.am
	* src/XmlRpcMethodImpl.cc
	* src/XmlRpcMethodImpl.h
	* src/XmlRpcRequest.cc
	* src/XmlRpcRequest.h
	* test/XmlRpcMethodTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-09-19 09:49:11 +00:00
parent f11ac122ac
commit c56a9bc669
11 changed files with 455 additions and 243 deletions

View File

@ -1,3 +1,23 @@
2010-09-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added keys parameter to aria2.tellStatus, aria2.tellActive,
aria2.tellWaiting and aria2.tellStopped XML-RPC method. 'keys' is
array of string. If it is specified, the response contains only
keys in 'keys' array. If 'keys' is empty or not specified, the
response contains all keys. This is useful when you just want
specific keys and avoid unnecessary transfers. For example,
*aria2.tellStatus*("1", ["gid", "status"]) returns 'gid' and
'status' key. Made get*Param() functions XmlRpcRequest's
methods and changed portions of the code that were affected by
this change.
* doc/aria2c.1.txt
* src/Makefile.am
* src/XmlRpcMethodImpl.cc
* src/XmlRpcMethodImpl.h
* src/XmlRpcRequest.cc
* src/XmlRpcRequest.h
* test/XmlRpcMethodTest.cc
2010-09-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Release 1.10.3

View File

@ -2,12 +2,12 @@
.\" Title: aria2c
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 09/15/2010
.\" Date: 09/19/2010
.\" Manual: Aria2 Manual
.\" Source: Aria2 1.10.3
.\" Language: English
.\"
.TH "ARIA2C" "1" "09/15/2010" "Aria2 1\&.10\&.3" "Aria2 Manual"
.TH "ARIA2C" "1" "09/19/2010" "Aria2 1\&.10\&.3" "Aria2 Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -2858,9 +2858,9 @@ This method changes the status of the download denoted by \fIgid\fR from "paused
.sp
This method is equal to calling \fBaria2\&.unpause\fR for every active/waiting download\&. This methods returns "OK" for success\&.
.sp
\fBaria2\&.tellStatus\fR \fIgid\fR
\fBaria2\&.tellStatus\fR \fIgid[, keys]\fR
.sp
This method returns download progress of the download denoted by \fIgid\fR\&. \fIgid\fR is of type string\&. The response is of type struct and it contains following keys\&. The value type is string\&.
This method returns download progress of the download denoted by \fIgid\fR\&. \fIgid\fR is of type string\&. \fIkeys\fR is array of string\&. If it is specified, the response contains only keys in \fIkeys\fR array\&. If \fIkeys\fR is empty or not specified, the response contains all keys\&. This is useful when you just want specific keys and avoid unnecessary transfers\&. For example, \fBaria2\&.tellStatus\fR("1", ["gid", "status"]) returns \fIgid\fR and \fIstatus\fR key\&. The response is of type struct and it contains following keys\&. The value type is string\&.
.PP
gid
.RS 4
@ -3125,13 +3125,13 @@ Download speed (byte/sec)
.RE
.RE
.sp
\fBaria2\&.tellActive\fR
\fBaria2\&.tellActive\fR \fI[keys]\fR
.sp
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\&.
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\&. For \fIkeys\fR parameter, please refer to \fBaria2\&.tellStatus\fR method\&.
.sp
\fBaria2\&.tellWaiting\fR \fIoffset, num\fR
\fBaria2\&.tellWaiting\fR \fIoffset, num, [keys]\fR
.sp
This method returns the list of waiting download, including paused downloads\&. \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\&.
This method returns the list of waiting download, including paused downloads\&. \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 \fIkeys\fR parameter, please refer to \fBaria2\&.tellStatus\fR method\&.
.sp
If offset is a positive integer, this method returns downloads in the range of [\fIoffset\fR, \fIoffset\fR+\fInum\fR)\&.
.sp
@ -3141,9 +3141,9 @@ For example, imagine that three downloads "A","B" and "C" are waiting in this or
.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
\fBaria2\&.tellStopped\fR \fIoffset, num, [keys]\fR
.sp
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\&.
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\&. For \fIkeys\fR parameter, please refer to \fBaria2\&.tellStatus\fR method\&.
.sp
\fIoffset\fR and \fInum\fR have the same semantics as \fBaria2\&.tellWaiting\fR method\&.
.sp

View File

@ -3338,9 +3338,14 @@ download.</p></div>
<div class="paragraph"><p><strong>aria2.unpauseAll</strong></p></div>
<div class="paragraph"><p>This method is equal to calling <strong>aria2.unpause</strong> for every active/waiting
download. This methods returns "OK" for success.</p></div>
<div class="paragraph"><p><strong>aria2.tellStatus</strong> <em>gid</em></p></div>
<div class="paragraph"><p><strong>aria2.tellStatus</strong> <em>gid[, keys]</em></p></div>
<div class="paragraph"><p>This method returns download progress of the download denoted by
<em>gid</em>. <em>gid</em> is of type string. The response is of type struct and it
<em>gid</em>. <em>gid</em> is of type string. <em>keys</em> is array of string. If it is
specified, the response contains only keys in <em>keys</em> array. If <em>keys</em>
is empty or not specified, the response contains all keys. This is
useful when you just want specific keys and avoid unnecessary
transfers. For example, <strong>aria2.tellStatus</strong>("1", ["gid", "status"])
returns <em>gid</em> and <em>status</em> key. The response is of type struct and it
contains following keys. The value type is string.</p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
@ -3779,15 +3784,17 @@ downloadSpeed
</dl></div>
</dd>
</dl></div>
<div class="paragraph"><p><strong>aria2.tellActive</strong></p></div>
<div class="paragraph"><p><strong>aria2.tellActive</strong> <em>[keys]</em></p></div>
<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. For <em>keys</em> parameter, please refer to
<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><strong>aria2.tellWaiting</strong> <em>offset, num, [keys]</em></p></div>
<div class="paragraph"><p>This method returns the list of waiting download, including paused
downloads. <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>
specifies the number of downloads to be returned. For <em>keys</em>
parameter, please refer to <strong>aria2.tellStatus</strong> method.</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
@ -3800,10 +3807,11 @@ in this order. aria2.tellWaiting(0, 1) returns
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><strong>aria2.tellStopped</strong> <em>offset, num, [keys]</em></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>
type integer and specifies the number of downloads to be returned.
For <em>keys</em> parameter, please refer to <strong>aria2.tellStatus</strong> method.</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
@ -4404,7 +4412,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-09-15 21:37:52 JST
Last updated 2010-09-19 18:43:46 JST
</div>
</div>
</body>

View File

@ -1549,10 +1549,15 @@ download.
This method is equal to calling *aria2.unpause* for every active/waiting
download. This methods returns "OK" for success.
*aria2.tellStatus* 'gid'
*aria2.tellStatus* 'gid[, keys]'
This method returns download progress of the download denoted by
'gid'. 'gid' is of type string. The response is of type struct and it
'gid'. 'gid' is of type string. 'keys' is array of string. If it is
specified, the response contains only keys in 'keys' array. If 'keys'
is empty or not specified, the response contains all keys. This is
useful when you just want specific keys and avoid unnecessary
transfers. For example, *aria2.tellStatus*("1", ["gid", "status"])
returns 'gid' and 'status' key. The response is of type struct and it
contains following keys. The value type is string.
gid::
@ -1801,18 +1806,20 @@ servers::
Download speed (byte/sec)
*aria2.tellActive*
*aria2.tellActive* '[keys]'
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. For 'keys' parameter, please refer to
*aria2.tellStatus* method.
*aria2.tellWaiting* 'offset, num'
*aria2.tellWaiting* 'offset, num, [keys]'
This method returns the list of waiting download, including paused
downloads. '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.
specifies the number of downloads to be returned. For 'keys'
parameter, please refer to *aria2.tellStatus* method.
If offset is a positive integer, this method returns downloads in the
range of ['offset', 'offset'+'num').
@ -1830,11 +1837,12 @@ 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'
*aria2.tellStopped* 'offset, num, [keys]'
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.
For 'keys' parameter, please refer to *aria2.tellStatus* method.
'offset' and 'num' have the same semantics as *aria2.tellWaiting*
method.

View File

@ -218,7 +218,7 @@ SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\
XmlRpcRequestParserState.h\
XmlRpcRequestParserStateImpl.cc XmlRpcRequestParserStateImpl.h\
XmlRpcElements.cc XmlRpcElements.h\
XmlRpcRequest.h\
XmlRpcRequest.cc XmlRpcRequest.h\
XmlRpcRequestProcessor.h\
HttpServerBodyCommand.cc HttpServerBodyCommand.h\
XmlRpcMethod.cc XmlRpcMethod.h\

View File

@ -42,7 +42,7 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_XML_RPC_TRUE@ XmlRpcRequestParserState.h\
@ENABLE_XML_RPC_TRUE@ XmlRpcRequestParserStateImpl.cc XmlRpcRequestParserStateImpl.h\
@ENABLE_XML_RPC_TRUE@ XmlRpcElements.cc XmlRpcElements.h\
@ENABLE_XML_RPC_TRUE@ XmlRpcRequest.h\
@ENABLE_XML_RPC_TRUE@ XmlRpcRequest.cc XmlRpcRequest.h\
@ENABLE_XML_RPC_TRUE@ XmlRpcRequestProcessor.h\
@ENABLE_XML_RPC_TRUE@ HttpServerBodyCommand.cc HttpServerBodyCommand.h\
@ENABLE_XML_RPC_TRUE@ XmlRpcMethod.cc XmlRpcMethod.h\
@ -452,10 +452,11 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
XmlRpcRequestParserStateMachine.cc \
XmlRpcRequestParserStateMachine.h XmlRpcRequestParserState.h \
XmlRpcRequestParserStateImpl.cc XmlRpcRequestParserStateImpl.h \
XmlRpcElements.cc XmlRpcElements.h XmlRpcRequest.h \
XmlRpcRequestProcessor.h HttpServerBodyCommand.cc \
HttpServerBodyCommand.h XmlRpcMethod.cc XmlRpcMethod.h \
XmlRpcMethodImpl.cc XmlRpcMethodImpl.h XmlRpcMethodFactory.cc \
XmlRpcElements.cc XmlRpcElements.h XmlRpcRequest.cc \
XmlRpcRequest.h XmlRpcRequestProcessor.h \
HttpServerBodyCommand.cc HttpServerBodyCommand.h \
XmlRpcMethod.cc XmlRpcMethod.h XmlRpcMethodImpl.cc \
XmlRpcMethodImpl.h XmlRpcMethodFactory.cc \
XmlRpcMethodFactory.h XmlRpcResponse.cc XmlRpcResponse.h \
HttpListenCommand.cc HttpListenCommand.h HttpServerCommand.cc \
HttpServerCommand.h HttpServerResponseCommand.cc \
@ -628,6 +629,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_XML_RPC_TRUE@ XmlRpcRequestParserStateMachine.$(OBJEXT) \
@ENABLE_XML_RPC_TRUE@ XmlRpcRequestParserStateImpl.$(OBJEXT) \
@ENABLE_XML_RPC_TRUE@ XmlRpcElements.$(OBJEXT) \
@ENABLE_XML_RPC_TRUE@ XmlRpcRequest.$(OBJEXT) \
@ENABLE_XML_RPC_TRUE@ HttpServerBodyCommand.$(OBJEXT) \
@ENABLE_XML_RPC_TRUE@ XmlRpcMethod.$(OBJEXT) \
@ENABLE_XML_RPC_TRUE@ XmlRpcMethodImpl.$(OBJEXT) \
@ -1655,6 +1657,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcMethod.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcMethodFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcMethodImpl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcRequest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcRequestParserController.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcRequestParserStateImpl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlRpcRequestParserStateMachine.Po@am__quote@

View File

@ -168,66 +168,26 @@ findRequestGroup(const SharedHandle<RequestGroupMan>& rgman, gid_t gid)
return group;
}
static const String* getStringParam
(const SharedHandle<List>& params, size_t index)
{
const String* stringParam = 0;
if(params->size() > index) {
stringParam = asString(params->get(index));
}
return stringParam;
}
static const Integer* getIntegerParam
(const SharedHandle<List>& params, size_t index)
{
const Integer* integerParam = 0;
if(params->size() > index) {
integerParam = asInteger(params->get(index));
}
return integerParam;
}
static const List* getListParam(const SharedHandle<List>& params, size_t index)
{
const List* listParam = 0;
if(params->size() > index) {
listParam = asList(params->get(index));
}
return listParam;
}
static const Dict* getDictParam(const SharedHandle<List>& params, size_t index)
{
const Dict* dictParam = 0;
if(params->size() > index) {
dictParam = asDict(params->get(index));
}
return dictParam;
}
static void getPosParam(const SharedHandle<List>& params, size_t posParamIndex,
static void getPosParam(const XmlRpcRequest& req, size_t posParamIndex,
bool& posGiven, size_t& pos)
{
if(params->size() > posParamIndex) {
const Integer* p = asInteger(params->get(posParamIndex));
if(p) {
if(p->i() >= 0) {
pos = p->i();
posGiven = true;
return;
} else {
throw DL_ABORT_EX("Position must be greater than or equal to 0.");
}
const Integer* p = req.getIntegerParam(posParamIndex);
if(p) {
if(p->i() >= 0) {
pos = p->i();
posGiven = true;
return;
} else {
throw DL_ABORT_EX("Position must be greater than or equal to 0.");
}
}
posGiven = false;
}
static gid_t getRequiredGidParam
(const SharedHandle<List>& params, size_t posParamIndex)
(const XmlRpcRequest& req, size_t posParamIndex)
{
const String* gidParam = getStringParam(params, posParamIndex);
const String* gidParam = req.getStringParam(posParamIndex);
if(gidParam) {
return util::parseLLInt(gidParam->s());
} else {
@ -252,19 +212,18 @@ static void extractUris(OutputIterator out, const List* src)
SharedHandle<ValueBase> AddUriXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
std::vector<std::string> uris;
extractUris(std::back_inserter(uris), getListParam(params, 0));
extractUris(std::back_inserter(uris), req.getListParam(0));
if(uris.empty()) {
throw DL_ABORT_EX("URI is not provided.");
}
SharedHandle<Option> requestOption(new Option(*e->getOption()));
gatherRequestOption(requestOption, getDictParam(params, 1));
gatherRequestOption(requestOption, req.getDictParam(1));
size_t pos = 0;
bool posGiven = false;
getPosParam(params, 2, posGiven, pos);
getPosParam(req, 2, posGiven, pos);
std::vector<SharedHandle<RequestGroup> > result;
createRequestGroupForUri(result, requestOption, uris,
@ -282,21 +241,20 @@ SharedHandle<ValueBase> AddUriXmlRpcMethod::process
SharedHandle<ValueBase> AddTorrentXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
const String* torrentParam = getStringParam(params, 0);
const String* torrentParam = req.getStringParam(0);
if(!torrentParam) {
throw DL_ABORT_EX("Torrent data is not provided.");
}
std::vector<std::string> uris;
extractUris(std::back_inserter(uris), getListParam(params, 1));
extractUris(std::back_inserter(uris), req.getListParam(1));
SharedHandle<Option> requestOption(new Option(*e->getOption()));
gatherRequestOption(requestOption, getDictParam(params, 2));
gatherRequestOption(requestOption, req.getDictParam(2));
size_t pos = 0;
bool posGiven = false;
getPosParam(params, 3, posGiven, pos);
getPosParam(req, 3, posGiven, pos);
std::vector<SharedHandle<RequestGroup> > result;
createRequestGroupForBitTorrent(result, requestOption,
@ -314,18 +272,17 @@ SharedHandle<ValueBase> AddTorrentXmlRpcMethod::process
SharedHandle<ValueBase> AddMetalinkXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
const String* metalinkParam = getStringParam(params, 0);
const String* metalinkParam = req.getStringParam(0);
if(!metalinkParam) {
throw DL_ABORT_EX("Metalink data is not provided.");
}
SharedHandle<Option> requestOption(new Option(*e->getOption()));
gatherRequestOption(requestOption, getDictParam(params, 1));
gatherRequestOption(requestOption, req.getDictParam(1));
size_t pos = 0;
bool posGiven = false;
getPosParam(params, 2, posGiven, pos);
getPosParam(req, 2, posGiven, pos);
std::vector<SharedHandle<RequestGroup> > result;
createRequestGroupForMetalink(result, requestOption, metalinkParam->s());
@ -348,8 +305,7 @@ SharedHandle<ValueBase> AddMetalinkXmlRpcMethod::process
static SharedHandle<ValueBase> removeDownload
(const XmlRpcRequest& req, DownloadEngine* e, bool forceRemove)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
e->getRequestGroupMan()->findRequestGroup(gid);
@ -416,8 +372,7 @@ static bool pauseRequestGroup
static SharedHandle<ValueBase> pauseDownload
(const XmlRpcRequest& req, DownloadEngine* e, bool forcePause)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
bool reserved = false;
SharedHandle<RequestGroup> group =
@ -484,8 +439,7 @@ SharedHandle<ValueBase> ForcePauseAllXmlRpcMethod::process
SharedHandle<ValueBase> UnpauseXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
e->getRequestGroupMan()->findReservedGroup(gid);
if(group.isNull() || !group->isPauseRequested()) {
@ -557,46 +511,84 @@ static void createFileEntry
}
}
void gatherProgressCommon
(const SharedHandle<Dict>& entryDict, const SharedHandle<RequestGroup>& group)
static bool requested_key
(const std::vector<std::string>& keys, const std::string& k)
{
entryDict->put(KEY_GID, util::itos(group->getGID()));
// This is "filtered" total length if --select-file is used.
entryDict->put(KEY_TOTAL_LENGTH, util::uitos(group->getTotalLength()));
// This is "filtered" total length if --select-file is used.
entryDict->put(KEY_COMPLETED_LENGTH,util::uitos(group->getCompletedLength()));
return keys.empty() || std::find(keys.begin(), keys.end(), k) != keys.end();
}
void gatherProgressCommon
(const SharedHandle<Dict>& entryDict,
const SharedHandle<RequestGroup>& group,
const std::vector<std::string>& keys)
{
if(requested_key(keys, KEY_GID)) {
entryDict->put(KEY_GID, util::itos(group->getGID()));
}
if(requested_key(keys, KEY_TOTAL_LENGTH)) {
// This is "filtered" total length if --select-file is used.
entryDict->put(KEY_TOTAL_LENGTH, util::uitos(group->getTotalLength()));
}
if(requested_key(keys, KEY_COMPLETED_LENGTH)) {
// This is "filtered" total length if --select-file is used.
entryDict->put
(KEY_COMPLETED_LENGTH,util::uitos(group->getCompletedLength()));
}
TransferStat stat = group->calculateStat();
entryDict->put(KEY_DOWNLOAD_SPEED, util::uitos(stat.getDownloadSpeed()));
entryDict->put(KEY_UPLOAD_SPEED, util::uitos(stat.getUploadSpeed()));
entryDict->put(KEY_UPLOAD_LENGTH, util::uitos(stat.getAllTimeUploadLength()));
entryDict->put(KEY_CONNECTIONS, util::uitos(group->getNumConnection()));
SharedHandle<PieceStorage> ps = group->getPieceStorage();
if(!ps.isNull()) {
if(ps->getBitfieldLength() > 0) {
entryDict->put(KEY_BITFIELD,
util::toHex(ps->getBitfield(), ps->getBitfieldLength()));
if(requested_key(keys, KEY_DOWNLOAD_SPEED)) {
entryDict->put(KEY_DOWNLOAD_SPEED, util::uitos(stat.getDownloadSpeed()));
}
if(requested_key(keys, KEY_UPLOAD_SPEED)) {
entryDict->put(KEY_UPLOAD_SPEED, util::uitos(stat.getUploadSpeed()));
}
if(requested_key(keys, KEY_UPLOAD_LENGTH)) {
entryDict->put
(KEY_UPLOAD_LENGTH, util::uitos(stat.getAllTimeUploadLength()));
}
if(requested_key(keys, KEY_CONNECTIONS)) {
entryDict->put(KEY_CONNECTIONS, util::uitos(group->getNumConnection()));
}
if(requested_key(keys, KEY_BITFIELD)) {
SharedHandle<PieceStorage> ps = group->getPieceStorage();
if(!ps.isNull()) {
if(ps->getBitfieldLength() > 0) {
entryDict->put(KEY_BITFIELD,
util::toHex(ps->getBitfield(), ps->getBitfieldLength()));
}
}
}
const SharedHandle<DownloadContext>& dctx = group->getDownloadContext();
entryDict->put(KEY_PIECE_LENGTH, util::uitos(dctx->getPieceLength()));
entryDict->put(KEY_NUM_PIECES, util::uitos(dctx->getNumPieces()));
if(!group->followedBy().empty()) {
SharedHandle<List> list = List::g();
// The element is GID.
for(std::vector<gid_t>::const_iterator i = group->followedBy().begin(),
eoi = group->followedBy().end(); i != eoi; ++i) {
list->append(util::itos(*i));
if(requested_key(keys, KEY_PIECE_LENGTH)) {
entryDict->put(KEY_PIECE_LENGTH, util::uitos(dctx->getPieceLength()));
}
if(requested_key(keys, KEY_NUM_PIECES)) {
entryDict->put(KEY_NUM_PIECES, util::uitos(dctx->getNumPieces()));
}
if(requested_key(keys, KEY_FOLLOWED_BY)) {
if(!group->followedBy().empty()) {
SharedHandle<List> list = List::g();
// The element is GID.
for(std::vector<gid_t>::const_iterator i = group->followedBy().begin(),
eoi = group->followedBy().end(); i != eoi; ++i) {
list->append(util::itos(*i));
}
entryDict->put(KEY_FOLLOWED_BY, list);
}
entryDict->put(KEY_FOLLOWED_BY, list);
}
if(group->belongsTo()) {
entryDict->put(KEY_BELONGS_TO, util::itos(group->belongsTo()));
if(requested_key(keys, KEY_BELONGS_TO)) {
if(group->belongsTo()) {
entryDict->put(KEY_BELONGS_TO, util::itos(group->belongsTo()));
}
}
if(requested_key(keys, KEY_FILES)) {
SharedHandle<List> files = List::g();
createFileEntry
(files, dctx->getFileEntries().begin(), dctx->getFileEntries().end());
entryDict->put(KEY_FILES, files);
}
if(requested_key(keys, KEY_DIR)) {
entryDict->put(KEY_DIR, dctx->getDir());
}
SharedHandle<List> files = List::g();
createFileEntry
(files, dctx->getFileEntries().begin(), dctx->getFileEntries().end());
entryDict->put(KEY_FILES, files);
entryDict->put(KEY_DIR, dctx->getDir());
}
#ifdef ENABLE_BITTORRENT
@ -635,21 +627,28 @@ void gatherBitTorrentMetadata
static void gatherProgressBitTorrent
(const SharedHandle<Dict>& entryDict,
const SharedHandle<TorrentAttribute>& torrentAttrs,
const BtObject& btObject)
const BtObject& btObject,
const std::vector<std::string>& keys)
{
entryDict->put(KEY_INFO_HASH, util::toHex(torrentAttrs->infoHash));
SharedHandle<Dict> btDict = Dict::g();
gatherBitTorrentMetadata(btDict, torrentAttrs);
entryDict->put(KEY_BITTORRENT, btDict);
if(btObject.isNull()) {
entryDict->put(KEY_NUM_SEEDERS, VLB_ZERO);
} else {
SharedHandle<PeerStorage> peerStorage = btObject.peerStorage_;
assert(!peerStorage.isNull());
std::vector<SharedHandle<Peer> > peers;
peerStorage->getActivePeers(peers);
entryDict->put(KEY_NUM_SEEDERS,
util::uitos(countSeeder(peers.begin(), peers.end())));
if(requested_key(keys, KEY_INFO_HASH)) {
entryDict->put(KEY_INFO_HASH, util::toHex(torrentAttrs->infoHash));
}
if(requested_key(keys, KEY_BITTORRENT)) {
SharedHandle<Dict> btDict = Dict::g();
gatherBitTorrentMetadata(btDict, torrentAttrs);
entryDict->put(KEY_BITTORRENT, btDict);
}
if(requested_key(keys, KEY_NUM_SEEDERS)) {
if(btObject.isNull()) {
entryDict->put(KEY_NUM_SEEDERS, VLB_ZERO);
} else {
SharedHandle<PeerStorage> peerStorage = btObject.peerStorage_;
assert(!peerStorage.isNull());
std::vector<SharedHandle<Peer> > peers;
peerStorage->getActivePeers(peers);
entryDict->put(KEY_NUM_SEEDERS,
util::uitos(countSeeder(peers.begin(), peers.end())));
}
}
}
@ -684,69 +683,107 @@ static void gatherPeer
static void gatherProgress
(const SharedHandle<Dict>& entryDict,
const SharedHandle<RequestGroup>& group, DownloadEngine* e)
const SharedHandle<RequestGroup>& group,
DownloadEngine* e,
const std::vector<std::string>& keys)
{
gatherProgressCommon(entryDict, group);
gatherProgressCommon(entryDict, group, keys);
#ifdef ENABLE_BITTORRENT
if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
SharedHandle<TorrentAttribute> torrentAttrs =
bittorrent::getTorrentAttrs(group->getDownloadContext());
BtObject btObject = e->getBtRegistry()->get(group->getGID());
gatherProgressBitTorrent(entryDict, torrentAttrs, btObject);
gatherProgressBitTorrent(entryDict, torrentAttrs, btObject, keys);
}
#endif // ENABLE_BITTORRENT
}
void gatherStoppedDownload
(const SharedHandle<Dict>& entryDict, const SharedHandle<DownloadResult>& ds)
(const SharedHandle<Dict>& entryDict, const SharedHandle<DownloadResult>& ds,
const std::vector<std::string>& keys)
{
entryDict->put(KEY_GID, util::itos(ds->gid));
entryDict->put(KEY_ERROR_CODE, util::itos(static_cast<int>(ds->result)));
if(ds->result == downloadresultcode::IN_PROGRESS) {
entryDict->put(KEY_STATUS, VLB_REMOVED);
} else if(ds->result == downloadresultcode::FINISHED) {
entryDict->put(KEY_STATUS, VLB_COMPLETE);
} else {
entryDict->put(KEY_STATUS, VLB_ERROR);
if(requested_key(keys, KEY_GID)) {
entryDict->put(KEY_GID, util::itos(ds->gid));
}
if(!ds->followedBy.empty()) {
SharedHandle<List> list = List::g();
// The element is GID.
for(std::vector<gid_t>::const_iterator i = ds->followedBy.begin(),
eoi = ds->followedBy.end(); i != eoi; ++i) {
list->append(util::itos(*i));
if(requested_key(keys, KEY_ERROR_CODE)) {
entryDict->put(KEY_ERROR_CODE, util::itos(static_cast<int>(ds->result)));
}
if(requested_key(keys, KEY_STATUS)) {
if(ds->result == downloadresultcode::IN_PROGRESS) {
entryDict->put(KEY_STATUS, VLB_REMOVED);
} else if(ds->result == downloadresultcode::FINISHED) {
entryDict->put(KEY_STATUS, VLB_COMPLETE);
} else {
entryDict->put(KEY_STATUS, VLB_ERROR);
}
entryDict->put(KEY_FOLLOWED_BY, list);
}
if(ds->belongsTo) {
entryDict->put(KEY_BELONGS_TO, util::itos(ds->belongsTo));
if(requested_key(keys, KEY_FOLLOWED_BY)) {
if(!ds->followedBy.empty()) {
SharedHandle<List> list = List::g();
// The element is GID.
for(std::vector<gid_t>::const_iterator i = ds->followedBy.begin(),
eoi = ds->followedBy.end(); i != eoi; ++i) {
list->append(util::itos(*i));
}
entryDict->put(KEY_FOLLOWED_BY, list);
}
}
SharedHandle<List> files = List::g();
createFileEntry(files, ds->fileEntries.begin(), ds->fileEntries.end());
entryDict->put(KEY_FILES, files);
entryDict->put(KEY_TOTAL_LENGTH, util::uitos(ds->totalLength));
entryDict->put(KEY_COMPLETED_LENGTH, util::uitos(ds->completedLength));
entryDict->put(KEY_UPLOAD_LENGTH, util::uitos(ds->uploadLength));
if(!ds->bitfieldStr.empty()) {
entryDict->put(KEY_BITFIELD, ds->bitfieldStr);
if(requested_key(keys, KEY_BELONGS_TO)) {
if(ds->belongsTo) {
entryDict->put(KEY_BELONGS_TO, util::itos(ds->belongsTo));
}
}
if(requested_key(keys, KEY_FILES)) {
SharedHandle<List> files = List::g();
createFileEntry(files, ds->fileEntries.begin(), ds->fileEntries.end());
entryDict->put(KEY_FILES, files);
}
if(requested_key(keys, KEY_TOTAL_LENGTH)) {
entryDict->put(KEY_TOTAL_LENGTH, util::uitos(ds->totalLength));
}
if(requested_key(keys, KEY_COMPLETED_LENGTH)) {
entryDict->put(KEY_COMPLETED_LENGTH, util::uitos(ds->completedLength));
}
if(requested_key(keys, KEY_UPLOAD_LENGTH)) {
entryDict->put(KEY_UPLOAD_LENGTH, util::uitos(ds->uploadLength));
}
if(requested_key(keys, KEY_BITFIELD)) {
if(!ds->bitfieldStr.empty()) {
entryDict->put(KEY_BITFIELD, ds->bitfieldStr);
}
}
if(requested_key(keys, KEY_DOWNLOAD_SPEED)) {
entryDict->put(KEY_DOWNLOAD_SPEED, VLB_ZERO);
}
if(requested_key(keys, KEY_UPLOAD_SPEED)) {
entryDict->put(KEY_UPLOAD_SPEED, VLB_ZERO);
}
entryDict->put(KEY_DOWNLOAD_SPEED, VLB_ZERO);
entryDict->put(KEY_UPLOAD_SPEED, VLB_ZERO);
if(!ds->infoHashStr.empty()) {
entryDict->put(KEY_INFO_HASH, ds->infoHashStr);
entryDict->put(KEY_NUM_SEEDERS, VLB_ZERO);
if(requested_key(keys, KEY_INFO_HASH)) {
entryDict->put(KEY_INFO_HASH, ds->infoHashStr);
}
if(requested_key(keys, KEY_NUM_SEEDERS)) {
entryDict->put(KEY_NUM_SEEDERS, VLB_ZERO);
}
}
if(requested_key(keys, KEY_PIECE_LENGTH)) {
entryDict->put(KEY_PIECE_LENGTH, util::uitos(ds->pieceLength));
}
if(requested_key(keys, KEY_NUM_PIECES)) {
entryDict->put(KEY_NUM_PIECES, util::uitos(ds->numPieces));
}
if(requested_key(keys, KEY_CONNECTIONS)) {
entryDict->put(KEY_CONNECTIONS, VLB_ZERO);
}
if(requested_key(keys, KEY_DIR)) {
entryDict->put(KEY_DIR, ds->dir);
}
entryDict->put(KEY_PIECE_LENGTH, util::uitos(ds->pieceLength));
entryDict->put(KEY_NUM_PIECES, util::uitos(ds->numPieces));
entryDict->put(KEY_CONNECTIONS, VLB_ZERO);
entryDict->put(KEY_DIR, ds->dir);
}
SharedHandle<ValueBase> GetFilesXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<List> files = List::g();
SharedHandle<RequestGroup> group =
findRequestGroup(e->getRequestGroupMan(), gid);
@ -771,8 +808,7 @@ SharedHandle<ValueBase> GetFilesXmlRpcMethod::process
SharedHandle<ValueBase> GetUrisXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
findRequestGroup(e->getRequestGroupMan(), gid);
if(group.isNull()) {
@ -792,8 +828,7 @@ SharedHandle<ValueBase> GetUrisXmlRpcMethod::process
SharedHandle<ValueBase> GetPeersXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
findRequestGroup(e->getRequestGroupMan(), gid);
@ -815,8 +850,11 @@ SharedHandle<ValueBase> GetPeersXmlRpcMethod::process
SharedHandle<ValueBase> TellStatusXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
const List* keysParam = req.getListParam(1);
std::vector<std::string> keys;
toStringList(std::back_inserter(keys), keysParam);
SharedHandle<RequestGroup> group =
e->getRequestGroupMan()->findRequestGroup(gid);
@ -832,18 +870,22 @@ SharedHandle<ValueBase> TellStatusXmlRpcMethod::process
(StringFormat("No such download for GID#%s",
util::itos(gid).c_str()).str());
}
gatherStoppedDownload(entryDict, ds);
gatherStoppedDownload(entryDict, ds, keys);
} else {
if(group->isPauseRequested()) {
entryDict->put(KEY_STATUS, VLB_PAUSED);
} else {
entryDict->put(KEY_STATUS, VLB_WAITING);
if(requested_key(keys, KEY_STATUS)) {
if(group->isPauseRequested()) {
entryDict->put(KEY_STATUS, VLB_PAUSED);
} else {
entryDict->put(KEY_STATUS, VLB_WAITING);
}
}
gatherProgress(entryDict, group, e);
gatherProgress(entryDict, group, e, keys);
}
} else {
entryDict->put(KEY_STATUS, VLB_ACTIVE);
gatherProgress(entryDict, group, e);
if(requested_key(keys, KEY_STATUS)) {
entryDict->put(KEY_STATUS, VLB_ACTIVE);
}
gatherProgress(entryDict, group, e, keys);
}
return entryDict;
}
@ -851,14 +893,19 @@ SharedHandle<ValueBase> TellStatusXmlRpcMethod::process
SharedHandle<ValueBase> TellActiveXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const List* keysParam = req.getListParam(0);
std::vector<std::string> keys;
toStringList(std::back_inserter(keys), keysParam);
SharedHandle<List> list = List::g();
const std::deque<SharedHandle<RequestGroup> >& groups =
e->getRequestGroupMan()->getRequestGroups();
for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
groups.begin(), eoi = groups.end(); i != eoi; ++i) {
SharedHandle<Dict> entryDict = Dict::g();
entryDict->put(KEY_STATUS, VLB_ACTIVE);
gatherProgress(entryDict, *i, e);
if(requested_key(keys, KEY_STATUS)) {
entryDict->put(KEY_STATUS, VLB_ACTIVE);
}
gatherProgress(entryDict, *i, e, keys);
list->append(entryDict);
}
return list;
@ -871,15 +918,19 @@ TellWaitingXmlRpcMethod::getItems(DownloadEngine* e) const
}
void TellWaitingXmlRpcMethod::createEntry
(const SharedHandle<Dict>& entryDict, const SharedHandle<RequestGroup>& item,
DownloadEngine* e) const
(const SharedHandle<Dict>& entryDict,
const SharedHandle<RequestGroup>& item,
DownloadEngine* e,
const std::vector<std::string>& keys) const
{
if(item->isPauseRequested()) {
entryDict->put(KEY_STATUS, VLB_PAUSED);
} else {
entryDict->put(KEY_STATUS, VLB_WAITING);
if(requested_key(keys, KEY_STATUS)) {
if(item->isPauseRequested()) {
entryDict->put(KEY_STATUS, VLB_PAUSED);
} else {
entryDict->put(KEY_STATUS, VLB_WAITING);
}
}
gatherProgress(entryDict, item, e);
gatherProgress(entryDict, item, e, keys);
}
const std::deque<SharedHandle<DownloadResult> >&
@ -889,10 +940,12 @@ TellStoppedXmlRpcMethod::getItems(DownloadEngine* e) const
}
void TellStoppedXmlRpcMethod::createEntry
(const SharedHandle<Dict>& entryDict, const SharedHandle<DownloadResult>& item,
DownloadEngine* e) const
(const SharedHandle<Dict>& entryDict,
const SharedHandle<DownloadResult>& item,
DownloadEngine* e,
const std::vector<std::string>& keys) const
{
gatherStoppedDownload(entryDict, item);
gatherStoppedDownload(entryDict, item, keys);
}
SharedHandle<ValueBase> PurgeDownloadResultXmlRpcMethod::process
@ -905,8 +958,7 @@ SharedHandle<ValueBase> PurgeDownloadResultXmlRpcMethod::process
SharedHandle<ValueBase> ChangeOptionXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
findRequestGroup(e->getRequestGroupMan(), gid);
@ -916,7 +968,7 @@ SharedHandle<ValueBase> ChangeOptionXmlRpcMethod::process
util::itos(gid).c_str()).str());
}
SharedHandle<Option> option(new Option());
const Dict* optionsParam = getDictParam(params, 1);
const Dict* optionsParam = req.getDictParam(1);
if(optionsParam) {
gatherChangeableOption(option, optionsParam);
applyChangeableOption(group->getOption().get(), option.get());
@ -942,8 +994,7 @@ SharedHandle<ValueBase> ChangeOptionXmlRpcMethod::process
SharedHandle<ValueBase> ChangeGlobalOptionXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
const Dict* optionsParam = getDictParam(params, 0);
const Dict* optionsParam = req.getDictParam(0);
if(!optionsParam) {
return VLB_OK;
}
@ -1012,8 +1063,7 @@ static void pushRequestOption
SharedHandle<ValueBase> GetOptionXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
findRequestGroup(e->getRequestGroupMan(), gid);
@ -1045,10 +1095,9 @@ SharedHandle<ValueBase> GetGlobalOptionXmlRpcMethod::process
SharedHandle<ValueBase> ChangePositionXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
const Integer* posParam = getIntegerParam(params, 1);
const String* howParam = getStringParam(params, 2);
gid_t gid = getRequiredGidParam(req, 0);
const Integer* posParam = req.getIntegerParam(1);
const String* howParam = req.getStringParam(2);
if(!posParam || !howParam) {
throw DL_ABORT_EX("Illegal argument.");
@ -1082,8 +1131,7 @@ SharedHandle<ValueBase> GetSessionInfoXmlRpcMethod::process
SharedHandle<ValueBase> GetServersXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
gid_t gid = getRequiredGidParam(req, 0);
SharedHandle<RequestGroup> group =
e->getRequestGroupMan()->findRequestGroup(gid);
if(group.isNull()) {
@ -1122,17 +1170,16 @@ SharedHandle<ValueBase> GetServersXmlRpcMethod::process
SharedHandle<ValueBase> ChangeUriXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
gid_t gid = getRequiredGidParam(params, 0);
const Integer* indexParam = getIntegerParam(params, 1);
const List* delUrisParam = getListParam(params, 2);
const List* addUrisParam = getListParam(params, 3);
gid_t gid = getRequiredGidParam(req, 0);
const Integer* indexParam = req.getIntegerParam(1);
const List* delUrisParam = req.getListParam(2);
const List* addUrisParam = req.getListParam(3);
if(!indexParam || !delUrisParam || ! addUrisParam) {
throw DL_ABORT_EX("Bad request");
}
size_t pos = 0;
bool posGiven = false;
getPosParam(params, 4, posGiven, pos);
getPosParam(req, 4, posGiven, pos);
size_t index = indexParam->i()-1;
SharedHandle<RequestGroup> group =
@ -1212,8 +1259,7 @@ SharedHandle<ValueBase> ForceShutdownXmlRpcMethod::process
SharedHandle<ValueBase> SystemMulticallXmlRpcMethod::process
(const XmlRpcRequest& req, DownloadEngine* e)
{
const SharedHandle<List>& params = req.params;
const List* methodSpecs = getListParam(params, 0);
const List* methodSpecs = req.getListParam(0);
if(!methodSpecs) {
throw DL_ABORT_EX("Illegal argument. One item list is expected.");
}

View File

@ -53,6 +53,21 @@ class RequestGroup;
namespace xmlrpc {
template<typename OutputIterator>
void toStringList(OutputIterator out, const List* src)
{
if(!src) {
return;
}
for(List::ValueType::const_iterator i = src->begin(), eoi = src->end();
i != eoi; ++i) {
const String* s = asString(*i);
if(s) {
*out++ = s->s();
}
}
}
class AddUriXmlRpcMethod:public XmlRpcMethod {
protected:
virtual SharedHandle<ValueBase> process
@ -311,7 +326,7 @@ private:
void checkPaginationParams(const SharedHandle<List>& params) const
{
if(params->size() != 2) {
if(params->size() < 2) {
throw DL_ABORT_EX("Invalid argument. Specify offset and num in integer.");
}
const Integer* p1 = asInteger(params->get(0));
@ -326,8 +341,11 @@ protected:
{
const SharedHandle<List>& params = req.params;
checkPaginationParams(params);
ssize_t offset = asInteger(params->get(0))->i();
size_t num = asInteger(params->get(1))->i();
ssize_t offset = req.getIntegerParam(0)->i();
size_t num = req.getIntegerParam(1)->i();
const List* keysParam = req.getListParam(2);
std::vector<std::string> keys;
toStringList(std::back_inserter(keys), keysParam);
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 =
@ -335,7 +353,7 @@ protected:
SharedHandle<List> list = List::g();
for(; range.first != range.second; ++range.first) {
SharedHandle<Dict> entryDict = Dict::g();
createEntry(entryDict, *range.first, e);
createEntry(entryDict, *range.first, e, keys);
list->append(entryDict);
}
if(offset < 0) {
@ -350,7 +368,8 @@ protected:
virtual void createEntry
(const SharedHandle<Dict>& entryDict,
const SharedHandle<T>& item,
DownloadEngine* e) const = 0;
DownloadEngine* e,
const std::vector<std::string>& keys) const = 0;
};
class TellWaitingXmlRpcMethod:
@ -362,7 +381,8 @@ protected:
virtual void createEntry
(const SharedHandle<Dict>& entryDict,
const SharedHandle<RequestGroup>& item,
DownloadEngine* e) const;
DownloadEngine* e,
const std::vector<std::string>& keys) const;
public:
static const std::string& getMethodName()
{
@ -380,7 +400,8 @@ protected:
virtual void createEntry
(const SharedHandle<Dict>& entryDict,
const SharedHandle<DownloadResult>& item,
DownloadEngine* e) const;
DownloadEngine* e,
const std::vector<std::string>& keys) const;
public:
static const std::string& getMethodName()
{
@ -530,12 +551,14 @@ protected:
// Helper function to store data to entryDict from ds. This function
// is used by tellStatus method.
void gatherStoppedDownload
(const SharedHandle<Dict>& entryDict, const SharedHandle<DownloadResult>& ds);
(const SharedHandle<Dict>& entryDict, const SharedHandle<DownloadResult>& ds,
const std::vector<std::string>& keys);
// Helper function to store data to entryDict from group. This
// function is used by tellStatus/tellActive/tellWaiting method
void gatherProgressCommon
(const SharedHandle<Dict>& entryDict, const SharedHandle<RequestGroup>& group);
(const SharedHandle<Dict>& entryDict, const SharedHandle<RequestGroup>& group,
const std::vector<std::string>& keys);
#ifdef ENABLE_BITTORRENT
// Helper function to store BitTorrent metadata from torrentAttrs.

79
src/XmlRpcRequest.cc Normal file
View File

@ -0,0 +1,79 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "XmlRpcRequest.h"
namespace aria2 {
namespace xmlrpc {
const String* XmlRpcRequest::getStringParam(size_t index) const
{
const String* stringParam = 0;
if(params->size() > index) {
stringParam = asString(params->get(index));
}
return stringParam;
}
const Integer* XmlRpcRequest::getIntegerParam(size_t index) const
{
const Integer* integerParam = 0;
if(params->size() > index) {
integerParam = asInteger(params->get(index));
}
return integerParam;
}
const List* XmlRpcRequest::getListParam(size_t index) const
{
const List* listParam = 0;
if(params->size() > index) {
listParam = asList(params->get(index));
}
return listParam;
}
const Dict* XmlRpcRequest::getDictParam(size_t index) const
{
const Dict* dictParam = 0;
if(params->size() > index) {
dictParam = asDict(params->get(index));
}
return dictParam;
}
} // namespace xmlrpc
} // namespace aria2

View File

@ -52,6 +52,14 @@ struct XmlRpcRequest {
XmlRpcRequest(const std::string& methodName,
const SharedHandle<List>& params):
methodName(methodName), params(params) {}
const String* getStringParam(size_t index) const;
const Integer* getIntegerParam(size_t index) const;
const List* getListParam(size_t index) const;
const Dict* getDictParam(size_t index) const;
};
} // namespace xmlrpc

View File

@ -728,13 +728,21 @@ void XmlRpcMethodTest::testGatherStoppedDownload()
d->followedBy = followedBy;
d->belongsTo = 2;
SharedHandle<Dict> entry = Dict::g();
gatherStoppedDownload(entry, d);
std::vector<std::string> keys;
gatherStoppedDownload(entry, d, keys);
const List* followedByRes = asList(entry->get("followedBy"));
CPPUNIT_ASSERT_EQUAL(std::string("3"), asString(followedByRes->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("4"), asString(followedByRes->get(1))->s());
CPPUNIT_ASSERT_EQUAL(std::string("2"),
asString(entry->get("belongsTo"))->s());
keys.push_back("gid");
entry = Dict::g();
gatherStoppedDownload(entry, d, keys);
CPPUNIT_ASSERT_EQUAL((size_t)1, entry->size());
CPPUNIT_ASSERT(entry->containsKey("gid"));
}
void XmlRpcMethodTest::testGatherProgressCommon()
@ -754,7 +762,8 @@ void XmlRpcMethodTest::testGatherProgressCommon()
group->belongsTo(2);
SharedHandle<Dict> entry = Dict::g();
gatherProgressCommon(entry, group);
std::vector<std::string> keys;
gatherProgressCommon(entry, group, keys);
const List* followedByRes = asList(entry->get("followedBy"));
CPPUNIT_ASSERT_EQUAL(util::itos(followedBy[0]->getGID()),
@ -775,6 +784,14 @@ void XmlRpcMethodTest::testGatherProgressCommon()
->get("uri"))
->s());
CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), asString(entry->get("dir"))->s());
keys.push_back("gid");
entry = Dict::g();
gatherProgressCommon(entry, group, keys);
CPPUNIT_ASSERT_EQUAL((size_t)1, entry->size());
CPPUNIT_ASSERT(entry->containsKey("gid"));
}
#ifdef ENABLE_BITTORRENT