Use XmlParser for XML-RPC.

pull/2/head
Tatsuhiro Tsujikawa 2011-11-11 00:37:32 +09:00
parent 3b4a368554
commit 787bfd75da
17 changed files with 609 additions and 1017 deletions

View File

@ -1,134 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 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 "ExpatXmlRpcRequestProcessor.h"
#include <stack>
#include <expat.h>
#include "XmlRpcRequestParserStateMachine.h"
#include "util.h"
#include "DlAbortEx.h"
#include "message.h"
namespace aria2 {
namespace rpc {
namespace {
struct SessionData {
XmlRpcRequestParserStateMachine* stm_;
std::stack<std::string> charactersStack_;
SessionData(XmlRpcRequestParserStateMachine* stm):stm_(stm) {}
};
} // namespace
namespace {
void mlStartElement(void* userData, const char* name, const char** attrs)
{
SessionData* sd = reinterpret_cast<SessionData*>(userData);
std::map<std::string, std::string> attrmap;
if(attrs) {
const char** p = attrs;
while(*p != 0) {
std::string name = *p++;
if(*p == 0) {
break;
}
std::string value = util::strip(*p++);
attrmap[name] = value;
}
}
sd->stm_->beginElement(name, attrmap);
if(sd->stm_->needsCharactersBuffering()) {
sd->charactersStack_.push(std::string());
}
}
} // namespace
namespace {
void mlEndElement(void* userData, const char* name)
{
SessionData* sd = reinterpret_cast<SessionData*>(userData);
std::string characters;
if(sd->stm_->needsCharactersBuffering()) {
characters = util::strip(sd->charactersStack_.top());
sd->charactersStack_.pop();
}
sd->stm_->endElement(name, characters);
}
} // namespace
namespace {
void mlCharacters(void* userData, const char* ch, int len)
{
SessionData* sd = reinterpret_cast<SessionData*>(userData);
if(sd->stm_->needsCharactersBuffering()) {
sd->charactersStack_.top().append(&ch[0], &ch[len]);
}
}
} // namespace
RpcRequest
XmlRpcRequestProcessor::parseMemory(const std::string& xml)
{
stm_.reset(new XmlRpcRequestParserStateMachine());
SharedHandle<SessionData> sessionData(new SessionData(stm_.get()));
XML_Parser parser = XML_ParserCreate(0);
XML_SetUserData(parser, sessionData.get());
XML_SetElementHandler(parser, &mlStartElement, &mlEndElement);
XML_SetCharacterDataHandler(parser, &mlCharacters);
int r = XML_Parse(parser, xml.data(), xml.size(), 1);
XML_ParserFree(parser);
if(r == XML_STATUS_ERROR) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
}
if(!downcast<List>(stm_->getCurrentFrameValue())) {
throw DL_ABORT_EX("Bad XML-RPC parameter list");
}
return RpcRequest(stm_->getMethodName(),
static_pointer_cast<List>(stm_->getCurrentFrameValue()));
}
} // namespace rpc
} // namespace aria2

View File

@ -56,8 +56,8 @@
#include "RpcMethodFactory.h" #include "RpcMethodFactory.h"
#include "RpcRequest.h" #include "RpcRequest.h"
#include "RpcResponse.h" #include "RpcResponse.h"
#include "rpc_helper.h"
#ifdef ENABLE_XML_RPC #ifdef ENABLE_XML_RPC
# include "XmlRpcRequestProcessor.h"
# include "XmlRpcRequestParserStateMachine.h" # include "XmlRpcRequestParserStateMachine.h"
#endif // ENABLE_XML_RPC #endif // ENABLE_XML_RPC
@ -213,8 +213,8 @@ bool HttpServerBodyCommand::execute()
// Do something for requestpath and body // Do something for requestpath and body
if(reqPath == "/rpc") { if(reqPath == "/rpc") {
#ifdef ENABLE_XML_RPC #ifdef ENABLE_XML_RPC
rpc::RpcRequest req = std::string body = httpServer_->getBody();
rpc::XmlRpcRequestProcessor().parseMemory(httpServer_->getBody()); rpc::RpcRequest req = rpc::xmlParseMemory(body.c_str(), body.size());
SharedHandle<rpc::RpcMethod> method = SharedHandle<rpc::RpcMethod> method =
rpc::RpcMethodFactory::create(req.methodName); rpc::RpcMethodFactory::create(req.methodName);
A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str())); A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str()));

View File

@ -222,7 +222,8 @@ SRCS = Socket.h\
SegList.h\ SegList.h\
NullHandle.h\ NullHandle.h\
a2iterator.h\ a2iterator.h\
paramed_string.cc paramed_string.h paramed_string.cc paramed_string.h\
rpc_helper.cc rpc_helper.h
if MINGW_BUILD if MINGW_BUILD
SRCS += WinConsoleFile.cc WinConsoleFile.h SRCS += WinConsoleFile.cc WinConsoleFile.h
@ -239,17 +240,8 @@ SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\
XmlRpcRequestParserStateMachine.cc XmlRpcRequestParserStateMachine.h\ XmlRpcRequestParserStateMachine.cc XmlRpcRequestParserStateMachine.h\
XmlRpcRequestParserState.h\ XmlRpcRequestParserState.h\
XmlRpcRequestParserStateImpl.cc XmlRpcRequestParserStateImpl.h\ XmlRpcRequestParserStateImpl.cc XmlRpcRequestParserStateImpl.h\
XmlRpcElements.cc XmlRpcElements.h\
XmlRpcRequestProcessor.h XmlRpcRequestProcessor.h
if HAVE_LIBXML2
SRCS += Xml2XmlRpcRequestProcessor.cc Xml2XmlRpcRequestProcessor.h
endif # HAVE_LIBXML2
if HAVE_LIBEXPAT
SRCS += ExpatXmlRpcRequestProcessor.cc ExpatXmlRpcRequestProcessor.h
endif # HAVE_LIBEXPAT
endif # ENABLE_XML_RPC endif # ENABLE_XML_RPC
if HAVE_SOME_FALLOCATE if HAVE_SOME_FALLOCATE

View File

@ -1,172 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 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 "Xml2XmlRpcRequestProcessor.h"
#include <cstring>
#include <stack>
#include <libxml/parser.h>
#include "XmlRpcRequestParserStateMachine.h"
#include "util.h"
#include "DlAbortEx.h"
#include "message.h"
namespace aria2 {
namespace rpc {
namespace {
struct SessionData {
XmlRpcRequestParserStateMachine* stm_;
std::stack<std::string> charactersStack_;
SessionData(XmlRpcRequestParserStateMachine* stm):stm_(stm) {}
};
} // namespace
namespace {
void mlStartElement(void* userData, const xmlChar* name,
const xmlChar** attrs)
{
SessionData* sd = reinterpret_cast<SessionData*>(userData);
std::map<std::string, std::string> attrmap;
if(attrs) {
const char** p = reinterpret_cast<const char**>(attrs);
while(*p != 0) {
std::string name = *p;
++p;
if(*p == 0) {
break;
}
attrmap[name].assign(*p, *p+strlen(*p));
++p;
}
}
sd->stm_->beginElement(reinterpret_cast<const char*>(name), attrmap);
if(sd->stm_->needsCharactersBuffering()) {
sd->charactersStack_.push(A2STR::NIL);
}
}
} // namespace
namespace {
void mlEndElement(void* userData, const xmlChar* name)
{
SessionData* sd = reinterpret_cast<SessionData*>(userData);
if(sd->stm_->needsCharactersBuffering()) {
sd->stm_->endElement(reinterpret_cast<const char*>(name),
sd->charactersStack_.top());
sd->charactersStack_.pop();
} else {
sd->stm_->endElement(reinterpret_cast<const char*>(name), A2STR::NIL);
}
}
} // namespace
namespace {
void mlCharacters(void* userData, const xmlChar* ch, int len)
{
SessionData* sd = reinterpret_cast<SessionData*>(userData);
if(sd->stm_->needsCharactersBuffering()) {
sd->charactersStack_.top().append(&ch[0], &ch[len]);
}
}
} // namespace
namespace {
xmlSAXHandler mySAXHandler =
{
0, // internalSubsetSAXFunc
0, // isStandaloneSAXFunc
0, // hasInternalSubsetSAXFunc
0, // hasExternalSubsetSAXFunc
0, // resolveEntitySAXFunc
0, // getEntitySAXFunc
0, // entityDeclSAXFunc
0, // notationDeclSAXFunc
0, // attributeDeclSAXFunc
0, // elementDeclSAXFunc
0, // unparsedEntityDeclSAXFunc
0, // setDocumentLocatorSAXFunc
0, // startDocumentSAXFunc
0, // endDocumentSAXFunc
&mlStartElement, // startElementSAXFunc
&mlEndElement, // endElementSAXFunc
0, // referenceSAXFunc
&mlCharacters, // charactersSAXFunc
0, // ignorableWhitespaceSAXFunc
0, // processingInstructionSAXFunc
0, // commentSAXFunc
0, // warningSAXFunc
0, // errorSAXFunc
0, // fatalErrorSAXFunc
0, // getParameterEntitySAXFunc
0, // cdataBlockSAXFunc
0, // externalSubsetSAXFunc
0, // unsigned int initialized
0, // void * _private
0, // startElementNsSAX2Func
0, // endElementNsSAX2Func
0, // xmlStructuredErrorFunc
};
} // namespace
XmlRpcRequestProcessor::XmlRpcRequestProcessor() {}
XmlRpcRequestProcessor::~XmlRpcRequestProcessor() {}
RpcRequest
XmlRpcRequestProcessor::parseMemory(const std::string& xml)
{
stm_.reset(new XmlRpcRequestParserStateMachine());
SharedHandle<SessionData> sessionData(new SessionData(stm_.get()));
int r = xmlSAXUserParseMemory(&mySAXHandler, sessionData.get(),
xml.data(), xml.size());
if(r != 0) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
}
if(!downcast<List>(stm_->getCurrentFrameValue())) {
throw DL_ABORT_EX("Bad XML-RPC parameter list");
}
return RpcRequest(stm_->getMethodName(),
static_pointer_cast<List>(stm_->getCurrentFrameValue()));
}
} // namespace rpc
} // namespace aria2

View File

@ -1,66 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 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 --> */
#ifndef D_XML2_XML_RPC_REQUEST_PROCESSOR_H
#define D_XML2_XML_RPC_REQUEST_PROCESSOR_H
#include "common.h"
#include <string>
#include "SharedHandle.h"
#include "RpcRequest.h"
namespace aria2 {
namespace rpc {
class XmlRpcRequestParserStateMachine;
class XmlRpcRequestProcessor {
private:
SharedHandle<XmlRpcRequestParserStateMachine> stm_;
public:
XmlRpcRequestProcessor();
~XmlRpcRequestProcessor();
RpcRequest parseMemory(const std::string& xml);
};
} // namespace rpc
} // namespace aria2
#endif // D_XML2_XML_RPC_REQUEST_PROCESSOR_H

View File

@ -1,61 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 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 "XmlRpcElements.h"
namespace aria2 {
namespace rpc {
namespace elements {
const std::string METHOD_CALL("methodCall");
const std::string METHOD_NAME("methodName");
const std::string A2_PARAMS("params");
const std::string PARAM("param");
const std::string VALUE("value");
const std::string I4("i4");
const std::string INT("int");
const std::string BOOLEAN("boolean");
const std::string STRING("string");
const std::string DOUBLE("double");
const std::string DATE_TIME_ISO8601("dateTime.iso8601");
const std::string BASE64("base64");
const std::string STRUCT("struct");
const std::string MEMBER("member");
const std::string NAME("name");
const std::string ARRAY("array");
const std::string DATA("data");
} // namespace elements
} // namespace rpc
} // namespace aria2

View File

@ -1,68 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 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 --> */
#ifndef D_XML_RPC_ELEMENTS_H
#define D_XML_RPC_ELEMENTS_H
#include "common.h"
#include <string>
namespace aria2 {
namespace rpc {
namespace elements {
extern const std::string METHOD_CALL;
extern const std::string METHOD_NAME;
extern const std::string A2_PARAMS;
extern const std::string PARAM;
extern const std::string VALUE;
extern const std::string I4;
extern const std::string INT;
extern const std::string BOOLEAN;
extern const std::string STRING;
extern const std::string DOUBLE;
extern const std::string DATE_TIME_ISO8601;
extern const std::string BASE64;
extern const std::string STRUCT;
extern const std::string MEMBER;
extern const std::string NAME;
extern const std::string ARRAY;
extern const std::string DATA;
} // namespace elements
} // namespace rpc
} // namespace aria2
#endif // D_XML_RPC_ELEMENTS_H

View File

@ -38,10 +38,12 @@
#include "common.h" #include "common.h"
#include <string> #include <string>
#include <map> #include <vector>
namespace aria2 { namespace aria2 {
class XmlAttr;
namespace rpc { namespace rpc {
class XmlRpcRequestParserStateMachine; class XmlRpcRequestParserStateMachine;
@ -50,11 +52,11 @@ class XmlRpcRequestParserState {
public: public:
virtual ~XmlRpcRequestParserState() {} virtual ~XmlRpcRequestParserState() {}
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs)= 0; const std::vector<XmlAttr>& attrs)= 0;
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) = 0; const std::string& characters) = 0;

View File

@ -33,11 +33,14 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "XmlRpcRequestParserStateImpl.h" #include "XmlRpcRequestParserStateImpl.h"
#include <cstring>
#include "XmlRpcRequestParserStateMachine.h" #include "XmlRpcRequestParserStateMachine.h"
#include "XmlRpcElements.h"
#include "RecoverableException.h" #include "RecoverableException.h"
#include "util.h" #include "util.h"
#include "base64.h" #include "base64.h"
#include "ValueBase.h"
namespace aria2 { namespace aria2 {
@ -46,19 +49,19 @@ namespace rpc {
// InitialXmlRpcRequestParserState // InitialXmlRpcRequestParserState
void InitialXmlRpcRequestParserState::beginElement void InitialXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::METHOD_CALL) { if(strcmp(name, "methodCall") == 0) {
stm->pushMethodCallState(); psm->pushMethodCallState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
void InitialXmlRpcRequestParserState::endElement void InitialXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{} {}
@ -66,140 +69,140 @@ void InitialXmlRpcRequestParserState::endElement
// UnknownElementXmlRpcRequestParserState // UnknownElementXmlRpcRequestParserState
void UnknownElementXmlRpcRequestParserState::beginElement void UnknownElementXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
// MethodCallXmlRpcRequestParserState // MethodCallXmlRpcRequestParserState
void MethodCallXmlRpcRequestParserState::beginElement void MethodCallXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::METHOD_NAME) { if(strcmp(name, "methodName") == 0) {
stm->pushMethodNameState(); psm->pushMethodNameState();
} else if(name == elements::A2_PARAMS) { } else if(strcmp(name, "params") == 0) {
stm->setCurrentFrameValue(List::g()); psm->setCurrentFrameValue(List::g());
stm->pushParamsState(); psm->pushParamsState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
// MethodNameXmlRpcRequestParserState // MethodNameXmlRpcRequestParserState
void MethodNameXmlRpcRequestParserState::beginElement void MethodNameXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
void MethodNameXmlRpcRequestParserState::endElement void MethodNameXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
stm->setMethodName(characters); psm->setMethodName(characters);
} }
// ParamsXmlRpcRequestParserState // ParamsXmlRpcRequestParserState
void ParamsXmlRpcRequestParserState::beginElement void ParamsXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::PARAM) { if(strcmp(name, "param") == 0) {
stm->pushFrame(); psm->pushFrame();
stm->pushParamState(); psm->pushParamState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
// ParamXmlRpcRequestParserState // ParamXmlRpcRequestParserState
void ParamXmlRpcRequestParserState::beginElement void ParamXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::VALUE) { if(strcmp(name, "value") == 0) {
stm->pushValueState(); psm->pushValueState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
void ParamXmlRpcRequestParserState::endElement void ParamXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
stm->popArrayFrame(); psm->popArrayFrame();
} }
// ValueXmlRpcRequestParserState // ValueXmlRpcRequestParserState
void ValueXmlRpcRequestParserState::beginElement void ValueXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::I4 || name == elements::INT) { if(strcmp(name, "i4") == 0 || strcmp(name, "int") == 0) {
stm->pushIntState(); psm->pushIntState();
} else if(name == elements::STRUCT) { } else if(strcmp(name, "struct") == 0) {
stm->setCurrentFrameValue(Dict::g()); psm->setCurrentFrameValue(Dict::g());
stm->pushStructState(); psm->pushStructState();
} else if(name == elements::ARRAY) { } else if(strcmp(name, "array") == 0) {
stm->setCurrentFrameValue(List::g()); psm->setCurrentFrameValue(List::g());
stm->pushArrayState(); psm->pushArrayState();
} else if(name == elements::STRING || name == elements::DOUBLE) { } else if(strcmp(name, "string") == 0 || strcmp(name, "double") == 0) {
stm->pushStringState(); psm->pushStringState();
} else if(name == elements::BASE64) { } else if(strcmp(name, "base64") == 0) {
stm->pushBase64State(); psm->pushBase64State();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
void ValueXmlRpcRequestParserState::endElement void ValueXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
// XML-RPC specification says that if no data type tag is used, the // XML-RPC specification says that if no data type tag is used, the
// data must be treated as string. To prevent from overwriting // data must be treated as string. To prevent from overwriting
// current frame value, we first check it is still null. // current frame value, we first check it is still null.
if(!stm->getCurrentFrameValue() && !characters.empty()) { if(!psm->getCurrentFrameValue() && !characters.empty()) {
stm->setCurrentFrameValue(String::g(characters)); psm->setCurrentFrameValue(String::g(characters));
} }
} }
// IntXmlRpcRequestParserState // IntXmlRpcRequestParserState
void IntXmlRpcRequestParserState::beginElement void IntXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
void IntXmlRpcRequestParserState::endElement void IntXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
try { try {
int64_t value = util::parseLLInt(characters.begin(), characters.end()); int64_t value = util::parseLLInt(characters.begin(), characters.end());
stm->setCurrentFrameValue(Integer::g(value)); psm->setCurrentFrameValue(Integer::g(value));
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
// nothing to do here: We just leave current frame value to null. // nothing to do here: We just leave current frame value to null.
} }
@ -208,135 +211,135 @@ void IntXmlRpcRequestParserState::endElement
// StringXmlRpcRequestParserState // StringXmlRpcRequestParserState
void StringXmlRpcRequestParserState::beginElement void StringXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
void StringXmlRpcRequestParserState::endElement void StringXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
stm->setCurrentFrameValue(String::g(characters)); psm->setCurrentFrameValue(String::g(characters));
} }
// Base64XmlRpcRequestParserState // Base64XmlRpcRequestParserState
void Base64XmlRpcRequestParserState::beginElement void Base64XmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
void Base64XmlRpcRequestParserState::endElement void Base64XmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
stm->setCurrentFrameValue psm->setCurrentFrameValue
(String::g(base64::decode(characters.begin(), characters.end()))); (String::g(base64::decode(characters.begin(), characters.end())));
} }
// StructXmlRpcRequestParserState // StructXmlRpcRequestParserState
void StructXmlRpcRequestParserState::beginElement void StructXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::MEMBER) { if(strcmp(name, "member") == 0) {
stm->pushFrame(); psm->pushFrame();
stm->pushMemberState(); psm->pushMemberState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
// MemberXmlRpcRequestParserState // MemberXmlRpcRequestParserState
void MemberXmlRpcRequestParserState::beginElement void MemberXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::NAME) { if(strcmp(name, "name") == 0) {
stm->pushNameState(); psm->pushNameState();
} else if(name == elements::VALUE) { } else if(strcmp(name, "value") == 0) {
stm->pushValueState(); psm->pushValueState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
void MemberXmlRpcRequestParserState::endElement void MemberXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
stm->popStructFrame(); psm->popStructFrame();
} }
// NameXmlRpcRequestParserState // NameXmlRpcRequestParserState
void NameXmlRpcRequestParserState::beginElement void NameXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
void NameXmlRpcRequestParserState::endElement void NameXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
stm->setCurrentFrameName(characters); psm->setCurrentFrameName(characters);
} }
// ArrayXmlRpcRequestParserState // ArrayXmlRpcRequestParserState
void ArrayXmlRpcRequestParserState::beginElement void ArrayXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::DATA) { if(strcmp(name, "data") == 0) {
stm->pushDataState(); psm->pushDataState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
// DataXmlRpcRequestParserState // DataXmlRpcRequestParserState
void DataXmlRpcRequestParserState::beginElement void DataXmlRpcRequestParserState::beginElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs) const std::vector<XmlAttr>& attrs)
{ {
if(name == elements::VALUE) { if(strcmp(name, "value") == 0) {
stm->pushFrame(); psm->pushFrame();
stm->pushArrayValueState(); psm->pushArrayValueState();
} else { } else {
stm->pushUnknownElementState(); psm->pushUnknownElementState();
} }
} }
// ArrayValueXmlRpcRequestParserState // ArrayValueXmlRpcRequestParserState
void ArrayValueXmlRpcRequestParserState::endElement void ArrayValueXmlRpcRequestParserState::endElement
(XmlRpcRequestParserStateMachine* stm, (XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) const std::string& characters)
{ {
ValueXmlRpcRequestParserState::endElement(stm, name, characters); ValueXmlRpcRequestParserState::endElement(psm, name, characters);
stm->popArrayFrame(); psm->popArrayFrame();
} }
} // namespace rpc } // namespace rpc

View File

@ -43,11 +43,11 @@ namespace rpc {
class InitialXmlRpcRequestParserState:public XmlRpcRequestParserState { class InitialXmlRpcRequestParserState:public XmlRpcRequestParserState {
public: public:
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -56,11 +56,11 @@ public:
class UnknownElementXmlRpcRequestParserState:public XmlRpcRequestParserState { class UnknownElementXmlRpcRequestParserState:public XmlRpcRequestParserState {
public: public:
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) {} const std::string& characters) {}
@ -69,11 +69,11 @@ public:
class MethodCallXmlRpcRequestParserState:public XmlRpcRequestParserState { class MethodCallXmlRpcRequestParserState:public XmlRpcRequestParserState {
public: public:
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) {} const std::string& characters) {}
@ -82,11 +82,11 @@ public:
class MethodNameXmlRpcRequestParserState:public XmlRpcRequestParserState { class MethodNameXmlRpcRequestParserState:public XmlRpcRequestParserState {
public: public:
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -94,11 +94,11 @@ public:
}; };
class ParamsXmlRpcRequestParserState:public XmlRpcRequestParserState { class ParamsXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) {} const std::string& characters) {}
@ -106,11 +106,11 @@ class ParamsXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class ParamXmlRpcRequestParserState:public XmlRpcRequestParserState { class ParamXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -118,11 +118,11 @@ class ParamXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class ValueXmlRpcRequestParserState:public XmlRpcRequestParserState { class ValueXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
protected: protected:
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -130,11 +130,11 @@ protected:
}; };
class IntXmlRpcRequestParserState:public XmlRpcRequestParserState { class IntXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -142,11 +142,11 @@ class IntXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class StringXmlRpcRequestParserState:public XmlRpcRequestParserState { class StringXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -154,11 +154,11 @@ class StringXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class Base64XmlRpcRequestParserState:public XmlRpcRequestParserState { class Base64XmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -166,11 +166,11 @@ class Base64XmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class StructXmlRpcRequestParserState:public XmlRpcRequestParserState { class StructXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) {} const std::string& characters) {}
@ -178,11 +178,11 @@ class StructXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class MemberXmlRpcRequestParserState:public XmlRpcRequestParserState { class MemberXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -190,11 +190,11 @@ class MemberXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class NameXmlRpcRequestParserState:public XmlRpcRequestParserState { class NameXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
@ -202,11 +202,11 @@ class NameXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class ArrayXmlRpcRequestParserState:public XmlRpcRequestParserState { class ArrayXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) {} const std::string& characters) {}
@ -214,11 +214,11 @@ class ArrayXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class DataXmlRpcRequestParserState:public XmlRpcRequestParserState { class DataXmlRpcRequestParserState:public XmlRpcRequestParserState {
virtual void beginElement(XmlRpcRequestParserStateMachine* stm, virtual void beginElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::map<std::string, std::string>& attrs); const std::vector<XmlAttr>& attrs);
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters) {} const std::string& characters) {}
@ -226,7 +226,7 @@ class DataXmlRpcRequestParserState:public XmlRpcRequestParserState {
}; };
class ArrayValueXmlRpcRequestParserState:public ValueXmlRpcRequestParserState { class ArrayValueXmlRpcRequestParserState:public ValueXmlRpcRequestParserState {
virtual void endElement(XmlRpcRequestParserStateMachine* stm, virtual void endElement(XmlRpcRequestParserStateMachine* psm,
const char* name, const char* name,
const std::string& characters); const std::string& characters);
}; };

View File

@ -2,7 +2,7 @@
/* /*
* aria2 - The high speed download utility * aria2 - The high speed download utility
* *
* Copyright (C) 2009 Tatsuhiro Tsujikawa * Copyright (C) 2011 Tatsuhiro Tsujikawa
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -33,79 +33,67 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "XmlRpcRequestParserStateMachine.h" #include "XmlRpcRequestParserStateMachine.h"
#include "XmlRpcRequestParserController.h"
#include "XmlRpcRequestParserStateImpl.h"
namespace aria2 { namespace aria2 {
namespace rpc { namespace rpc {
namespace {
InitialXmlRpcRequestParserState* InitialXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::initialState_ = initialState = new InitialXmlRpcRequestParserState();
new InitialXmlRpcRequestParserState();
UnknownElementXmlRpcRequestParserState* UnknownElementXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::unknownElementState_ = unknownElementState = new UnknownElementXmlRpcRequestParserState();
new UnknownElementXmlRpcRequestParserState();
MethodCallXmlRpcRequestParserState* MethodCallXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::methodCallState_ = methodCallState = new MethodCallXmlRpcRequestParserState();
new MethodCallXmlRpcRequestParserState();
MethodNameXmlRpcRequestParserState* MethodNameXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::methodNameState_ = methodNameState = new MethodNameXmlRpcRequestParserState();
new MethodNameXmlRpcRequestParserState();
ParamsXmlRpcRequestParserState* ParamsXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::paramsState_ = paramsState = new ParamsXmlRpcRequestParserState();
new ParamsXmlRpcRequestParserState();
ParamXmlRpcRequestParserState* ParamXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::paramState_ = paramState = new ParamXmlRpcRequestParserState();
new ParamXmlRpcRequestParserState();
ValueXmlRpcRequestParserState* ValueXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::valueState_ = valueState = new ValueXmlRpcRequestParserState();
new ValueXmlRpcRequestParserState();
IntXmlRpcRequestParserState* IntXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::intState_ = intState = new IntXmlRpcRequestParserState();
new IntXmlRpcRequestParserState();
StringXmlRpcRequestParserState* StringXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::stringState_ = stringState = new StringXmlRpcRequestParserState();
new StringXmlRpcRequestParserState();
Base64XmlRpcRequestParserState* Base64XmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::base64State_ = base64State = new Base64XmlRpcRequestParserState();
new Base64XmlRpcRequestParserState();
StructXmlRpcRequestParserState* StructXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::structState_ = structState = new StructXmlRpcRequestParserState();
new StructXmlRpcRequestParserState();
MemberXmlRpcRequestParserState* MemberXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::memberState_ = memberState = new MemberXmlRpcRequestParserState();
new MemberXmlRpcRequestParserState();
NameXmlRpcRequestParserState* NameXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::nameState_ = nameState = new NameXmlRpcRequestParserState();
new NameXmlRpcRequestParserState();
ArrayXmlRpcRequestParserState* ArrayXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::arrayState_ = arrayState = new ArrayXmlRpcRequestParserState();
new ArrayXmlRpcRequestParserState();
DataXmlRpcRequestParserState* DataXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::dataState_ = dataState = new DataXmlRpcRequestParserState();
new DataXmlRpcRequestParserState();
ArrayValueXmlRpcRequestParserState* ArrayValueXmlRpcRequestParserState*
XmlRpcRequestParserStateMachine::arrayValueState_ = arrayValueState = new ArrayValueXmlRpcRequestParserState();
new ArrayValueXmlRpcRequestParserState(); } // namespace
XmlRpcRequestParserStateMachine::XmlRpcRequestParserStateMachine(): XmlRpcRequestParserStateMachine::XmlRpcRequestParserStateMachine():
controller_(new XmlRpcRequestParserController()) controller_(new XmlRpcRequestParserController())
{ {
stateStack_.push(initialState_); stateStack_.push(initialState);
} }
XmlRpcRequestParserStateMachine::~XmlRpcRequestParserStateMachine() XmlRpcRequestParserStateMachine::~XmlRpcRequestParserStateMachine()
@ -113,6 +101,154 @@ XmlRpcRequestParserStateMachine::~XmlRpcRequestParserStateMachine()
delete controller_; delete controller_;
} }
bool XmlRpcRequestParserStateMachine::needsCharactersBuffering() const
{
return stateStack_.top()->needsCharactersBuffering();
}
bool XmlRpcRequestParserStateMachine::finished() const
{
return stateStack_.top() == initialState;
}
void XmlRpcRequestParserStateMachine::beginElement
(const char* localname,
const char* prefix,
const char* nsUri,
const std::vector<XmlAttr>& attrs)
{
stateStack_.top()->beginElement(this, localname, attrs);
}
void XmlRpcRequestParserStateMachine::endElement
(const char* localname,
const char* prefix,
const char* nsUri,
const std::string& characters)
{
stateStack_.top()->endElement(this, localname, characters);
stateStack_.pop();
}
void XmlRpcRequestParserStateMachine::setMethodName
(const std::string& methodName)
{
controller_->setMethodName(methodName);
}
const std::string& XmlRpcRequestParserStateMachine::getMethodName() const
{
return controller_->getMethodName();
}
void XmlRpcRequestParserStateMachine::popArrayFrame()
{
controller_->popArrayFrame();
}
void XmlRpcRequestParserStateMachine::popStructFrame()
{
controller_->popStructFrame();
}
void XmlRpcRequestParserStateMachine::pushFrame()
{
controller_->pushFrame();
}
void XmlRpcRequestParserStateMachine::setCurrentFrameValue
(const SharedHandle<ValueBase>& value)
{
controller_->setCurrentFrameValue(value);
}
const SharedHandle<ValueBase>&
XmlRpcRequestParserStateMachine::getCurrentFrameValue() const
{
return controller_->getCurrentFrameValue();
}
void XmlRpcRequestParserStateMachine::setCurrentFrameName
(const std::string& name)
{
controller_->setCurrentFrameName(name);
}
void XmlRpcRequestParserStateMachine::pushUnknownElementState()
{
stateStack_.push(unknownElementState);
}
void XmlRpcRequestParserStateMachine::pushMethodCallState()
{
stateStack_.push(methodCallState);
}
void XmlRpcRequestParserStateMachine::pushMethodNameState()
{
stateStack_.push(methodNameState);
}
void XmlRpcRequestParserStateMachine::pushParamsState()
{
stateStack_.push(paramsState);
}
void XmlRpcRequestParserStateMachine::pushParamState()
{
stateStack_.push(paramState);
}
void XmlRpcRequestParserStateMachine::pushValueState()
{
stateStack_.push(valueState);
}
void XmlRpcRequestParserStateMachine::pushIntState()
{
stateStack_.push(intState);
}
void XmlRpcRequestParserStateMachine::pushStringState()
{
stateStack_.push(stringState);
}
void XmlRpcRequestParserStateMachine::pushBase64State()
{
stateStack_.push(base64State);
}
void XmlRpcRequestParserStateMachine::pushStructState()
{
stateStack_.push(structState);
}
void XmlRpcRequestParserStateMachine::pushMemberState()
{
stateStack_.push(memberState);
}
void XmlRpcRequestParserStateMachine::pushNameState()
{
stateStack_.push(nameState);
}
void XmlRpcRequestParserStateMachine::pushArrayState()
{
stateStack_.push(arrayState);
}
void XmlRpcRequestParserStateMachine::pushDataState()
{
stateStack_.push(dataState);
}
void XmlRpcRequestParserStateMachine::pushArrayValueState()
{
stateStack_.push(arrayValueState);
}
} // namespace rpc } // namespace rpc
} // namespace aria2 } // namespace aria2

View File

@ -2,7 +2,7 @@
/* /*
* aria2 - The high speed download utility * aria2 - The high speed download utility
* *
* Copyright (C) 2009 Tatsuhiro Tsujikawa * Copyright (C) 2011 Tatsuhiro Tsujikawa
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -35,134 +35,69 @@
#ifndef D_XML_RPC_REQUEST_PARSER_STATE_MACHINE_H #ifndef D_XML_RPC_REQUEST_PARSER_STATE_MACHINE_H
#define D_XML_RPC_REQUEST_PARSER_STATE_MACHINE_H #define D_XML_RPC_REQUEST_PARSER_STATE_MACHINE_H
#include "common.h" #include "ParserStateMachine.h"
#include <string> #include <string>
#include <map>
#include <stack> #include <stack>
#include "XmlRpcRequestParserController.h" #include "SharedHandle.h"
#include "XmlRpcRequestParserStateImpl.h"
#include "ValueBase.h"
namespace aria2 { namespace aria2 {
class ValueBase;
namespace rpc { namespace rpc {
class XmlRpcRequestParserStateMachine { class XmlRpcRequestParserController;
private: class XmlRpcRequestParserState;
XmlRpcRequestParserController* controller_;
std::stack<XmlRpcRequestParserState*> stateStack_; class XmlRpcRequestParserStateMachine : public ParserStateMachine {
static InitialXmlRpcRequestParserState* initialState_;
static MethodCallXmlRpcRequestParserState* methodCallState_;
static MethodNameXmlRpcRequestParserState* methodNameState_;
static ParamsXmlRpcRequestParserState* paramsState_;
static ParamXmlRpcRequestParserState* paramState_;
static ValueXmlRpcRequestParserState* valueState_;
static IntXmlRpcRequestParserState* intState_;
static StringXmlRpcRequestParserState* stringState_;
static Base64XmlRpcRequestParserState* base64State_;
static StructXmlRpcRequestParserState* structState_;
static MemberXmlRpcRequestParserState* memberState_;
static NameXmlRpcRequestParserState* nameState_;
static ArrayXmlRpcRequestParserState* arrayState_;
static DataXmlRpcRequestParserState* dataState_;
static ArrayValueXmlRpcRequestParserState* arrayValueState_;
static UnknownElementXmlRpcRequestParserState* unknownElementState_;
public: public:
XmlRpcRequestParserStateMachine(); XmlRpcRequestParserStateMachine();
virtual ~XmlRpcRequestParserStateMachine();
~XmlRpcRequestParserStateMachine(); virtual bool needsCharactersBuffering() const;
virtual bool finished() const;
void beginElement(const char* name, virtual void beginElement
const std::map<std::string, std::string>& attrs) (const char* localname,
{ const char* prefix,
stateStack_.top()->beginElement(this, name, attrs); const char* nsUri,
} const std::vector<XmlAttr>& attrs);
void endElement(const char* name, const std::string& characters)
{
stateStack_.top()->endElement(this, name, characters);
stateStack_.pop();
}
void setMethodName(const std::string& methodName) virtual void endElement
{ (const char* localname,
controller_->setMethodName(methodName); const char* prefix,
} const char* nsUri,
const std::string& characters);
const std::string& getMethodName() const void setMethodName(const std::string& methodName);
{ const std::string& getMethodName() const;
return controller_->getMethodName(); void popArrayFrame();
} void popStructFrame();
void pushFrame();
void setCurrentFrameValue(const SharedHandle<ValueBase>& value);
const SharedHandle<ValueBase>& getCurrentFrameValue() const;
void setCurrentFrameName(const std::string& name);
void popArrayFrame() void pushUnknownElementState();
{ void pushMethodCallState();
controller_->popArrayFrame(); void pushMethodNameState();
} void pushParamsState();
void pushParamState();
void popStructFrame() void pushValueState();
{ void pushIntState();
controller_->popStructFrame(); void pushStringState();
} void pushBase64State();
void pushStructState();
void pushFrame() void pushMemberState();
{ void pushNameState();
controller_->pushFrame(); void pushArrayState();
} void pushDataState();
void pushArrayValueState();
void setCurrentFrameValue(const SharedHandle<ValueBase>& value) private:
{ std::stack<XmlRpcRequestParserState*> stateStack_;
controller_->setCurrentFrameValue(value); XmlRpcRequestParserController* controller_;
}
const SharedHandle<ValueBase>& getCurrentFrameValue() const
{
return controller_->getCurrentFrameValue();
}
void setCurrentFrameName(const std::string& name)
{
controller_->setCurrentFrameName(name);
}
bool needsCharactersBuffering() const
{
return stateStack_.top()->needsCharactersBuffering();
}
void pushUnknownElementState() { stateStack_.push(unknownElementState_); }
void pushMethodCallState() { stateStack_.push(methodCallState_); }
void pushMethodNameState() { stateStack_.push(methodNameState_); }
void pushParamsState() { stateStack_.push(paramsState_); }
void pushParamState() { stateStack_.push(paramState_); }
void pushValueState() { stateStack_.push(valueState_); }
void pushIntState() { stateStack_.push(intState_); }
void pushStringState() { stateStack_.push(stringState_); }
void pushBase64State() { stateStack_.push(base64State_); }
void pushStructState() { stateStack_.push(structState_); }
void pushMemberState() { stateStack_.push(memberState_); }
void pushNameState() { stateStack_.push(nameState_); }
void pushArrayState() { stateStack_.push(arrayState_); }
void pushDataState() { stateStack_.push(dataState_); }
void pushArrayValueState() { stateStack_.push(arrayValueState_); }
}; };
} // namespace rpc } // namespace rpc

View File

@ -2,7 +2,7 @@
/* /*
* aria2 - The high speed download utility * aria2 - The high speed download utility
* *
* Copyright (C) 2009 Tatsuhiro Tsujikawa * Copyright (C) 2011 Tatsuhiro Tsujikawa
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -32,31 +32,32 @@
* files in the program, then also delete it here. * files in the program, then also delete it here.
*/ */
/* copyright --> */ /* copyright --> */
#ifndef D_EXPAT_XML_RPC_REQUEST_PROCESSOR_H #include "rpc_helper.h"
#define D_EXPAT_XML_RPC_REQUEST_PROCESSOR_H #include "XmlParser.h"
#include "common.h"
#include <string>
#include "SharedHandle.h"
#include "RpcRequest.h" #include "RpcRequest.h"
#include "XmlRpcRequestParserStateMachine.h"
#include "message.h"
#include "DlAbortEx.h"
namespace aria2 { namespace aria2 {
namespace rpc { namespace rpc {
class XmlRpcRequestParserStateMachine; #ifdef ENABLE_XML_RPC
RpcRequest xmlParseMemory(const char* xml, size_t size)
class XmlRpcRequestProcessor { {
private: XmlRpcRequestParserStateMachine psm;
SharedHandle<XmlRpcRequestParserStateMachine> stm_; if(!XmlParser(&psm).parseMemory(xml, size)) {
public: throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
RpcRequest parseMemory(const std::string& xml); }
}; if(!downcast<List>(psm.getCurrentFrameValue())) {
throw DL_ABORT_EX("Bad XML-RPC parameter list");
}
return RpcRequest(psm.getMethodName(),
static_pointer_cast<List>(psm.getCurrentFrameValue()));
}
#endif // ENABLE_XML_RPC
} // namespace rpc } // namespace rpc
} // namespace aria2 } // namespace aria2
#endif // D_EXPAT_XML_RPC_REQUEST_PROCESSOR_H

View File

@ -2,7 +2,7 @@
/* /*
* aria2 - The high speed download utility * aria2 - The high speed download utility
* *
* Copyright (C) 2009 Tatsuhiro Tsujikawa * Copyright (C) 2011 Tatsuhiro Tsujikawa
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -32,15 +32,25 @@
* files in the program, then also delete it here. * files in the program, then also delete it here.
*/ */
/* copyright --> */ /* copyright --> */
#ifndef D_XML_RPC_REQUEST_PROCESSOR_H #ifndef D_RPC_HELPER_H
#define D_XML_RPC_REQUEST_PROCESSOR_H #define D_RPC_HELPER_H
#include "common.h" #include "common.h"
#ifdef HAVE_LIBXML2 #include <cstdlib>
# include "Xml2XmlRpcRequestProcessor.h"
#elif HAVE_LIBEXPAT
# include "ExpatXmlRpcRequestProcessor.h"
#endif // HAVE_LIBEXPAT
#endif // D_XML_RPC_REQUEST_PROCESSOR_H namespace aria2 {
namespace rpc {
class RpcRequest;
#ifdef ENABLE_XML_RPC
RpcRequest xmlParseMemory(const char* xml, size_t size);
#endif // ENABLE_XML_RPC
} // namespace rpc
} // namespace aria2
#endif // D_RPC_HELPER_H

View File

@ -79,11 +79,11 @@ aria2c_SOURCES = AllTest.cc\
BufferedFileTest.cc\ BufferedFileTest.cc\
GeomStreamPieceSelectorTest.cc\ GeomStreamPieceSelectorTest.cc\
SegListTest.cc\ SegListTest.cc\
ParamedStringTest.cc ParamedStringTest.cc\
RpcHelperTest.cc
if ENABLE_XML_RPC if ENABLE_XML_RPC
aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\ aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc
XmlRpcRequestProcessorTest.cc
endif # ENABLE_XML_RPC endif # ENABLE_XML_RPC
if HAVE_SOME_FALLOCATE if HAVE_SOME_FALLOCATE

187
test/RpcHelperTest.cc Normal file
View File

@ -0,0 +1,187 @@
#include "rpc_helper.h"
#include <cppunit/extensions/HelperMacros.h>
#include "RpcRequest.h"
#include "RecoverableException.h"
#ifdef ENABLE_XML_RPC
# include "XmlRpcRequestParserStateMachine.h"
#endif // ENABLE_XML_RPC
namespace aria2 {
namespace rpc {
class RpcHelperTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(RpcHelperTest);
#ifdef ENABLE_XML_RPC
CPPUNIT_TEST(testParseMemory);
CPPUNIT_TEST(testParseMemory_shouldFail);
CPPUNIT_TEST(testParseMemory_withoutStringTag);
#endif // ENABLE_XML_RPC
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
#ifdef ENABLE_XML_RPC
void testParseMemory();
void testParseMemory_shouldFail();
void testParseMemory_withoutStringTag();
#endif // ENABLE_XML_RPC
};
CPPUNIT_TEST_SUITE_REGISTRATION(RpcHelperTest);
#ifdef ENABLE_XML_RPC
void RpcHelperTest::testParseMemory()
{
std::string s =
"<?xml version=\"1.0\"?>"
"<methodCall>"
" <methodName>aria2.addURI</methodName>"
" <params>"
" <param>"
" <value><i4>100</i4></value>"
" </param>"
" <param>"
" <value>"
" <struct>"
" <member>"
" <name>max-count</name>"
" <value><i4>65535</i4></value>"
" </member>"
" <member>"
" <name>seed-ratio</name>"
" <value><double>0.99</double></value>"
" </member>"
" </struct>"
" </value>"
" </param>"
" <param>"
" <value>"
" <array>"
" <data>"
" <value><string>pudding</string></value>"
" <value><base64>aGVsbG8gd29ybGQ=</base64></value>"
" </data>"
" </array>"
" </value>"
" </param>"
" </params>"
"</methodCall>";
RpcRequest req = xmlParseMemory(s.c_str(), s.size());
CPPUNIT_ASSERT_EQUAL(std::string("aria2.addURI"), req.methodName);
CPPUNIT_ASSERT_EQUAL((size_t)3, req.params->size());
CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100,
downcast<Integer>(req.params->get(0))->i());
const Dict* dict = downcast<Dict>(req.params->get(1));
CPPUNIT_ASSERT_EQUAL((Integer::ValueType)65535,
downcast<Integer>(dict->get("max-count"))->i());
// Current implementation handles double as string.
CPPUNIT_ASSERT_EQUAL(std::string("0.99"),
downcast<String>(dict->get("seed-ratio"))->s());
const List* list = downcast<List>(req.params->get(2));
CPPUNIT_ASSERT_EQUAL(std::string("pudding"), downcast<String>(list->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("hello world"), downcast<String>(list->get(1))->s());
}
void RpcHelperTest::testParseMemory_shouldFail()
{
try {
std::string s =
"<methodCall>"
" <methodName>aria2.addURI</methodName>"
" <params>"
" <param>"
" <value><i4>100</i4></value>"
" </param>";
xmlParseMemory(s.c_str(), s.size());
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// success
}
{
std::string s =
"<methodCall>"
" <methodName>aria2.addURI</methodName>"
" <params>"
" </params>"
"</methodCall>";
RpcRequest req = xmlParseMemory(s.c_str(), s.size());
CPPUNIT_ASSERT(req.params);
}
try {
std::string s =
"<methodCall>"
" <methodName>aria2.addURI</methodName>"
"</methodCall>";
xmlParseMemory(s.c_str(), s.size());
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// success
}
}
void RpcHelperTest::testParseMemory_withoutStringTag()
{
std::string s =
"<?xml version=\"1.0\"?>"
"<methodCall>"
" <methodName>aria2.addUri</methodName>"
" <params>"
" <param>"
" <value>http://aria2.sourceforge.net</value>"
" </param>"
" <param>"
" <value>http://aria2.<foo/>sourceforge.net</value>"
" </param>"
" <param>"
" <value>"
" <struct>"
" <member>"
" <name>hello</name>"
" <value>world</value>"
" </member>"
" </struct>"
" </value>"
" </param>"
" <param>"
" <value>"
" <array>"
" <data>"
" <value>apple</value>"
" <value>banana</value>"
" <value><string>lemon</string>peanuts</value>"
" </data>"
" </array>"
" </value>"
" </param>"
" </params>"
"</methodCall>";
RpcRequest req =
xmlParseMemory(s.c_str(), s.size());
CPPUNIT_ASSERT_EQUAL((size_t)4, req.params->size());
CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net"),
downcast<String>(req.params->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net"),
downcast<String>(req.params->get(1))->s());
const Dict* dict = downcast<Dict>(req.params->get(2));
CPPUNIT_ASSERT_EQUAL(std::string("world"),
downcast<String>(dict->get("hello"))->s());
const List* list = downcast<List>(req.params->get(3));
CPPUNIT_ASSERT_EQUAL(std::string("apple"), downcast<String>(list->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("banana"), downcast<String>(list->get(1))->s());
CPPUNIT_ASSERT_EQUAL(std::string("lemon"), downcast<String>(list->get(2))->s());
}
#endif // ENABLE_XML_RPC
} // namespace rpc
} // namespace aria2

View File

@ -1,173 +0,0 @@
#include "XmlRpcRequestProcessor.h"
#include <cppunit/extensions/HelperMacros.h>
#include "XmlRpcRequestParserStateMachine.h"
#include "RecoverableException.h"
namespace aria2 {
namespace rpc {
class XmlRpcRequestProcessorTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(XmlRpcRequestProcessorTest);
CPPUNIT_TEST(testParseMemory);
CPPUNIT_TEST(testParseMemory_shouldFail);
CPPUNIT_TEST(testParseMemory_withoutStringTag);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void testParseMemory();
void testParseMemory_shouldFail();
void testParseMemory_withoutStringTag();
};
CPPUNIT_TEST_SUITE_REGISTRATION(XmlRpcRequestProcessorTest);
void XmlRpcRequestProcessorTest::testParseMemory()
{
XmlRpcRequestProcessor proc;
RpcRequest req =
proc.parseMemory("<?xml version=\"1.0\"?>"
"<methodCall>"
" <methodName>aria2.addURI</methodName>"
" <params>"
" <param>"
" <value><i4>100</i4></value>"
" </param>"
" <param>"
" <value>"
" <struct>"
" <member>"
" <name>max-count</name>"
" <value><i4>65535</i4></value>"
" </member>"
" <member>"
" <name>seed-ratio</name>"
" <value><double>0.99</double></value>"
" </member>"
" </struct>"
" </value>"
" </param>"
" <param>"
" <value>"
" <array>"
" <data>"
" <value><string>pudding</string></value>"
" <value><base64>aGVsbG8gd29ybGQ=</base64></value>"
" </data>"
" </array>"
" </value>"
" </param>"
" </params>"
"</methodCall>");
CPPUNIT_ASSERT_EQUAL(std::string("aria2.addURI"), req.methodName);
CPPUNIT_ASSERT_EQUAL((size_t)3, req.params->size());
CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100,
downcast<Integer>(req.params->get(0))->i());
const Dict* dict = downcast<Dict>(req.params->get(1));
CPPUNIT_ASSERT_EQUAL((Integer::ValueType)65535,
downcast<Integer>(dict->get("max-count"))->i());
// Current implementation handles double as string.
CPPUNIT_ASSERT_EQUAL(std::string("0.99"),
downcast<String>(dict->get("seed-ratio"))->s());
const List* list = downcast<List>(req.params->get(2));
CPPUNIT_ASSERT_EQUAL(std::string("pudding"), downcast<String>(list->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("hello world"), downcast<String>(list->get(1))->s());
}
void XmlRpcRequestProcessorTest::testParseMemory_shouldFail()
{
XmlRpcRequestProcessor proc;
try {
proc.parseMemory("<methodCall>"
" <methodName>aria2.addURI</methodName>"
" <params>"
" <param>"
" <value><i4>100</i4></value>"
" </param>");
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// success
}
{
RpcRequest req =
proc.parseMemory("<methodCall>"
" <methodName>aria2.addURI</methodName>"
" <params>"
" </params>"
"</methodCall>");
CPPUNIT_ASSERT(req.params);
}
try {
RpcRequest req =
proc.parseMemory("<methodCall>"
" <methodName>aria2.addURI</methodName>"
"</methodCall>");
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// success
}
}
void XmlRpcRequestProcessorTest::testParseMemory_withoutStringTag()
{
XmlRpcRequestProcessor proc;
RpcRequest req =
proc.parseMemory("<?xml version=\"1.0\"?>"
"<methodCall>"
" <methodName>aria2.addUri</methodName>"
" <params>"
" <param>"
" <value>http://aria2.sourceforge.net</value>"
" </param>"
" <param>"
" <value>http://aria2.<foo/>sourceforge.net</value>"
" </param>"
" <param>"
" <value>"
" <struct>"
" <member>"
" <name>hello</name>"
" <value>world</value>"
" </member>"
" </struct>"
" </value>"
" </param>"
" <param>"
" <value>"
" <array>"
" <data>"
" <value>apple</value>"
" <value>banana</value>"
" <value><string>lemon</string>peanuts</value>"
" </data>"
" </array>"
" </value>"
" </param>"
" </params>"
"</methodCall>");
CPPUNIT_ASSERT_EQUAL((size_t)4, req.params->size());
CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net"),
downcast<String>(req.params->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net"),
downcast<String>(req.params->get(1))->s());
const Dict* dict = downcast<Dict>(req.params->get(2));
CPPUNIT_ASSERT_EQUAL(std::string("world"),
downcast<String>(dict->get("hello"))->s());
const List* list = downcast<List>(req.params->get(3));
CPPUNIT_ASSERT_EQUAL(std::string("apple"), downcast<String>(list->get(0))->s());
CPPUNIT_ASSERT_EQUAL(std::string("banana"), downcast<String>(list->get(1))->s());
CPPUNIT_ASSERT_EQUAL(std::string("lemon"), downcast<String>(list->get(2))->s());
}
} // namespace rpc
} // namespace aria2