diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2011-11-11 00:37:32 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2011-11-11 00:37:32 +0900 |
| commit | 787bfd75dabaec2ff269cc0c1661046679ad91fe (patch) | |
| tree | 693a3cdeba2e61f974ccdbfe9bc38f14f4bd0c8e | |
| parent | 3b4a368554478f07dc9ac4edeb9bbe8004abab50 (diff) | |
Use XmlParser for XML-RPC.
| -rw-r--r-- | src/ExpatXmlRpcRequestProcessor.cc | 134 | ||||
| -rw-r--r-- | src/HttpServerBodyCommand.cc | 6 | ||||
| -rw-r--r-- | src/Makefile.am | 12 | ||||
| -rw-r--r-- | src/Xml2XmlRpcRequestProcessor.cc | 172 | ||||
| -rw-r--r-- | src/Xml2XmlRpcRequestProcessor.h | 66 | ||||
| -rw-r--r-- | src/XmlRpcElements.cc | 61 | ||||
| -rw-r--r-- | src/XmlRpcElements.h | 68 | ||||
| -rw-r--r-- | src/XmlRpcRequestParserState.h | 10 | ||||
| -rw-r--r-- | src/XmlRpcRequestParserStateImpl.cc | 209 | ||||
| -rw-r--r-- | src/XmlRpcRequestParserStateImpl.h | 92 | ||||
| -rw-r--r-- | src/XmlRpcRequestParserStateMachine.cc | 204 | ||||
| -rw-r--r-- | src/XmlRpcRequestParserStateMachine.h | 169 | ||||
| -rw-r--r-- | src/rpc_helper.cc (renamed from src/ExpatXmlRpcRequestProcessor.h) | 39 | ||||
| -rw-r--r-- | src/rpc_helper.h (renamed from src/XmlRpcRequestProcessor.h) | 28 | ||||
| -rw-r--r-- | test/Makefile.am | 6 | ||||
| -rw-r--r-- | test/RpcHelperTest.cc | 187 | ||||
| -rw-r--r-- | test/XmlRpcRequestProcessorTest.cc | 173 |
17 files changed, 614 insertions, 1022 deletions
diff --git a/src/ExpatXmlRpcRequestProcessor.cc b/src/ExpatXmlRpcRequestProcessor.cc deleted file mode 100644 index f2e2f804..00000000 --- a/src/ExpatXmlRpcRequestProcessor.cc +++ /dev/null @@ -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 diff --git a/src/HttpServerBodyCommand.cc b/src/HttpServerBodyCommand.cc index 6f6f02bb..9e0db7a9 100644 --- a/src/HttpServerBodyCommand.cc +++ b/src/HttpServerBodyCommand.cc @@ -56,8 +56,8 @@ #include "RpcMethodFactory.h" #include "RpcRequest.h" #include "RpcResponse.h" +#include "rpc_helper.h" #ifdef ENABLE_XML_RPC -# include "XmlRpcRequestProcessor.h" # include "XmlRpcRequestParserStateMachine.h" #endif // ENABLE_XML_RPC @@ -213,8 +213,8 @@ bool HttpServerBodyCommand::execute() // Do something for requestpath and body if(reqPath == "/rpc") { #ifdef ENABLE_XML_RPC - rpc::RpcRequest req = - rpc::XmlRpcRequestProcessor().parseMemory(httpServer_->getBody()); + std::string body = httpServer_->getBody(); + rpc::RpcRequest req = rpc::xmlParseMemory(body.c_str(), body.size()); SharedHandle<rpc::RpcMethod> method = rpc::RpcMethodFactory::create(req.methodName); A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str())); diff --git a/src/Makefile.am b/src/Makefile.am index cf387618..5d87e1ca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -222,7 +222,8 @@ SRCS = Socket.h\ SegList.h\ NullHandle.h\ a2iterator.h\ - paramed_string.cc paramed_string.h + paramed_string.cc paramed_string.h\ + rpc_helper.cc rpc_helper.h if MINGW_BUILD SRCS += WinConsoleFile.cc WinConsoleFile.h @@ -239,17 +240,8 @@ SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\ XmlRpcRequestParserStateMachine.cc XmlRpcRequestParserStateMachine.h\ XmlRpcRequestParserState.h\ XmlRpcRequestParserStateImpl.cc XmlRpcRequestParserStateImpl.h\ - XmlRpcElements.cc XmlRpcElements.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 if HAVE_SOME_FALLOCATE diff --git a/src/Xml2XmlRpcRequestProcessor.cc b/src/Xml2XmlRpcRequestProcessor.cc deleted file mode 100644 index 171b90ff..00000000 --- a/src/Xml2XmlRpcRequestProcessor.cc +++ /dev/null @@ -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 diff --git a/src/Xml2XmlRpcRequestProcessor.h b/src/Xml2XmlRpcRequestProcessor.h deleted file mode 100644 index da1298aa..00000000 --- a/src/Xml2XmlRpcRequestProcessor.h +++ /dev/null @@ -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 diff --git a/src/XmlRpcElements.cc b/src/XmlRpcElements.cc deleted file mode 100644 index 68243258..00000000 --- a/src/XmlRpcElements.cc +++ /dev/null @@ -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 diff --git a/src/XmlRpcElements.h b/src/XmlRpcElements.h deleted file mode 100644 index c0214aed..00000000 --- a/src/XmlRpcElements.h +++ /dev/null @@ -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 diff --git a/src/XmlRpcRequestParserState.h b/src/XmlRpcRequestParserState.h index 96721b59..69138234 100644 --- a/src/XmlRpcRequestParserState.h +++ b/src/XmlRpcRequestParserState.h @@ -38,10 +38,12 @@ #include "common.h" #include <string> -#include <map> +#include <vector> namespace aria2 { +class XmlAttr; + namespace rpc { class XmlRpcRequestParserStateMachine; @@ -50,11 +52,11 @@ class XmlRpcRequestParserState { public: virtual ~XmlRpcRequestParserState() {} - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) = 0; diff --git a/src/XmlRpcRequestParserStateImpl.cc b/src/XmlRpcRequestParserStateImpl.cc index 062689d2..a71ec3e8 100644 --- a/src/XmlRpcRequestParserStateImpl.cc +++ b/src/XmlRpcRequestParserStateImpl.cc @@ -33,11 +33,14 @@ */ /* copyright --> */ #include "XmlRpcRequestParserStateImpl.h" + +#include <cstring> + #include "XmlRpcRequestParserStateMachine.h" -#include "XmlRpcElements.h" #include "RecoverableException.h" #include "util.h" #include "base64.h" +#include "ValueBase.h" namespace aria2 { @@ -46,19 +49,19 @@ namespace rpc { // InitialXmlRpcRequestParserState void InitialXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::METHOD_CALL) { - stm->pushMethodCallState(); + if(strcmp(name, "methodCall") == 0) { + psm->pushMethodCallState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } void InitialXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) {} @@ -66,140 +69,140 @@ void InitialXmlRpcRequestParserState::endElement // UnknownElementXmlRpcRequestParserState void UnknownElementXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } // MethodCallXmlRpcRequestParserState void MethodCallXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::METHOD_NAME) { - stm->pushMethodNameState(); - } else if(name == elements::A2_PARAMS) { - stm->setCurrentFrameValue(List::g()); - stm->pushParamsState(); + if(strcmp(name, "methodName") == 0) { + psm->pushMethodNameState(); + } else if(strcmp(name, "params") == 0) { + psm->setCurrentFrameValue(List::g()); + psm->pushParamsState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } // MethodNameXmlRpcRequestParserState void MethodNameXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } void MethodNameXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - stm->setMethodName(characters); + psm->setMethodName(characters); } // ParamsXmlRpcRequestParserState void ParamsXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::PARAM) { - stm->pushFrame(); - stm->pushParamState(); + if(strcmp(name, "param") == 0) { + psm->pushFrame(); + psm->pushParamState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } // ParamXmlRpcRequestParserState void ParamXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::VALUE) { - stm->pushValueState(); + if(strcmp(name, "value") == 0) { + psm->pushValueState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } void ParamXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - stm->popArrayFrame(); + psm->popArrayFrame(); } // ValueXmlRpcRequestParserState void ValueXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::I4 || name == elements::INT) { - stm->pushIntState(); - } else if(name == elements::STRUCT) { - stm->setCurrentFrameValue(Dict::g()); - stm->pushStructState(); - } else if(name == elements::ARRAY) { - stm->setCurrentFrameValue(List::g()); - stm->pushArrayState(); - } else if(name == elements::STRING || name == elements::DOUBLE) { - stm->pushStringState(); - } else if(name == elements::BASE64) { - stm->pushBase64State(); + if(strcmp(name, "i4") == 0 || strcmp(name, "int") == 0) { + psm->pushIntState(); + } else if(strcmp(name, "struct") == 0) { + psm->setCurrentFrameValue(Dict::g()); + psm->pushStructState(); + } else if(strcmp(name, "array") == 0) { + psm->setCurrentFrameValue(List::g()); + psm->pushArrayState(); + } else if(strcmp(name, "string") == 0 || strcmp(name, "double") == 0) { + psm->pushStringState(); + } else if(strcmp(name, "base64") == 0) { + psm->pushBase64State(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } void ValueXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { // XML-RPC specification says that if no data type tag is used, the // data must be treated as string. To prevent from overwriting // current frame value, we first check it is still null. - if(!stm->getCurrentFrameValue() && !characters.empty()) { - stm->setCurrentFrameValue(String::g(characters)); + if(!psm->getCurrentFrameValue() && !characters.empty()) { + psm->setCurrentFrameValue(String::g(characters)); } } // IntXmlRpcRequestParserState void IntXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } void IntXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { try { int64_t value = util::parseLLInt(characters.begin(), characters.end()); - stm->setCurrentFrameValue(Integer::g(value)); + psm->setCurrentFrameValue(Integer::g(value)); } catch(RecoverableException& e) { // nothing to do here: We just leave current frame value to null. } @@ -208,135 +211,135 @@ void IntXmlRpcRequestParserState::endElement // StringXmlRpcRequestParserState void StringXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } void StringXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - stm->setCurrentFrameValue(String::g(characters)); + psm->setCurrentFrameValue(String::g(characters)); } // Base64XmlRpcRequestParserState void Base64XmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } void Base64XmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - stm->setCurrentFrameValue + psm->setCurrentFrameValue (String::g(base64::decode(characters.begin(), characters.end()))); } // StructXmlRpcRequestParserState void StructXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::MEMBER) { - stm->pushFrame(); - stm->pushMemberState(); + if(strcmp(name, "member") == 0) { + psm->pushFrame(); + psm->pushMemberState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } // MemberXmlRpcRequestParserState void MemberXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::NAME) { - stm->pushNameState(); - } else if(name == elements::VALUE) { - stm->pushValueState(); + if(strcmp(name, "name") == 0) { + psm->pushNameState(); + } else if(strcmp(name, "value") == 0) { + psm->pushValueState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } void MemberXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - stm->popStructFrame(); + psm->popStructFrame(); } // NameXmlRpcRequestParserState void NameXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } void NameXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - stm->setCurrentFrameName(characters); + psm->setCurrentFrameName(characters); } // ArrayXmlRpcRequestParserState void ArrayXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::DATA) { - stm->pushDataState(); + if(strcmp(name, "data") == 0) { + psm->pushDataState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } // DataXmlRpcRequestParserState void DataXmlRpcRequestParserState::beginElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs) + const std::vector<XmlAttr>& attrs) { - if(name == elements::VALUE) { - stm->pushFrame(); - stm->pushArrayValueState(); + if(strcmp(name, "value") == 0) { + psm->pushFrame(); + psm->pushArrayValueState(); } else { - stm->pushUnknownElementState(); + psm->pushUnknownElementState(); } } // ArrayValueXmlRpcRequestParserState void ArrayValueXmlRpcRequestParserState::endElement -(XmlRpcRequestParserStateMachine* stm, +(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters) { - ValueXmlRpcRequestParserState::endElement(stm, name, characters); - stm->popArrayFrame(); + ValueXmlRpcRequestParserState::endElement(psm, name, characters); + psm->popArrayFrame(); } } // namespace rpc diff --git a/src/XmlRpcRequestParserStateImpl.h b/src/XmlRpcRequestParserStateImpl.h index 2da57769..6636865a 100644 --- a/src/XmlRpcRequestParserStateImpl.h +++ b/src/XmlRpcRequestParserStateImpl.h @@ -43,11 +43,11 @@ namespace rpc { class InitialXmlRpcRequestParserState:public XmlRpcRequestParserState { public: - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -56,11 +56,11 @@ public: class UnknownElementXmlRpcRequestParserState:public XmlRpcRequestParserState { public: - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) {} @@ -69,11 +69,11 @@ public: class MethodCallXmlRpcRequestParserState:public XmlRpcRequestParserState { public: - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) {} @@ -82,11 +82,11 @@ public: class MethodNameXmlRpcRequestParserState:public XmlRpcRequestParserState { public: - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -94,11 +94,11 @@ public: }; class ParamsXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) {} @@ -106,11 +106,11 @@ class ParamsXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class ParamXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -118,11 +118,11 @@ class ParamXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class ValueXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, const char* name, - const std::map<std::string, std::string>& attrs); + const std::vector<XmlAttr>& attrs); protected: - virtual void endElement(XmlRpcRequestParserStateMachine* stm, + virtual void endElement(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters); @@ -130,11 +130,11 @@ protected: }; class IntXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -142,11 +142,11 @@ class IntXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class StringXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -154,11 +154,11 @@ class StringXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class Base64XmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -166,11 +166,11 @@ class Base64XmlRpcRequestParserState:public XmlRpcRequestParserState { }; class StructXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) {} @@ -178,11 +178,11 @@ class StructXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class MemberXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -190,11 +190,11 @@ class MemberXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class NameXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters); @@ -202,11 +202,11 @@ class NameXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class ArrayXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) {} @@ -214,11 +214,11 @@ class ArrayXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class DataXmlRpcRequestParserState:public XmlRpcRequestParserState { - virtual void beginElement(XmlRpcRequestParserStateMachine* stm, + virtual void beginElement(XmlRpcRequestParserStateMachine* psm, 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 std::string& characters) {} @@ -226,7 +226,7 @@ class DataXmlRpcRequestParserState:public XmlRpcRequestParserState { }; class ArrayValueXmlRpcRequestParserState:public ValueXmlRpcRequestParserState { - virtual void endElement(XmlRpcRequestParserStateMachine* stm, + virtual void endElement(XmlRpcRequestParserStateMachine* psm, const char* name, const std::string& characters); }; diff --git a/src/XmlRpcRequestParserStateMachine.cc b/src/XmlRpcRequestParserStateMachine.cc index 22fe1511..db3013f8 100644 --- a/src/XmlRpcRequestParserStateMachine.cc +++ b/src/XmlRpcRequestParserStateMachine.cc @@ -2,7 +2,7 @@ /* * 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 * it under the terms of the GNU General Public License as published by @@ -33,79 +33,67 @@ */ /* copyright --> */ #include "XmlRpcRequestParserStateMachine.h" +#include "XmlRpcRequestParserController.h" +#include "XmlRpcRequestParserStateImpl.h" namespace aria2 { namespace rpc { +namespace { InitialXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::initialState_ = - new InitialXmlRpcRequestParserState(); +initialState = new InitialXmlRpcRequestParserState(); UnknownElementXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::unknownElementState_ = - new UnknownElementXmlRpcRequestParserState(); +unknownElementState = new UnknownElementXmlRpcRequestParserState(); MethodCallXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::methodCallState_ = - new MethodCallXmlRpcRequestParserState(); +methodCallState = new MethodCallXmlRpcRequestParserState(); MethodNameXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::methodNameState_ = - new MethodNameXmlRpcRequestParserState(); +methodNameState = new MethodNameXmlRpcRequestParserState(); ParamsXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::paramsState_ = - new ParamsXmlRpcRequestParserState(); +paramsState = new ParamsXmlRpcRequestParserState(); ParamXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::paramState_ = - new ParamXmlRpcRequestParserState(); +paramState = new ParamXmlRpcRequestParserState(); ValueXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::valueState_ = - new ValueXmlRpcRequestParserState(); +valueState = new ValueXmlRpcRequestParserState(); IntXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::intState_ = - new IntXmlRpcRequestParserState(); +intState = new IntXmlRpcRequestParserState(); StringXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::stringState_ = - new StringXmlRpcRequestParserState(); +stringState = new StringXmlRpcRequestParserState(); Base64XmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::base64State_ = - new Base64XmlRpcRequestParserState(); +base64State = new Base64XmlRpcRequestParserState(); StructXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::structState_ = - new StructXmlRpcRequestParserState(); +structState = new StructXmlRpcRequestParserState(); MemberXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::memberState_ = - new MemberXmlRpcRequestParserState(); +memberState = new MemberXmlRpcRequestParserState(); NameXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::nameState_ = - new NameXmlRpcRequestParserState(); +nameState = new NameXmlRpcRequestParserState(); ArrayXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::arrayState_ = - new ArrayXmlRpcRequestParserState(); +arrayState = new ArrayXmlRpcRequestParserState(); DataXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::dataState_ = - new DataXmlRpcRequestParserState(); +dataState = new DataXmlRpcRequestParserState(); ArrayValueXmlRpcRequestParserState* -XmlRpcRequestParserStateMachine::arrayValueState_ = - new ArrayValueXmlRpcRequestParserState(); +arrayValueState = new ArrayValueXmlRpcRequestParserState(); +} // namespace XmlRpcRequestParserStateMachine::XmlRpcRequestParserStateMachine(): controller_(new XmlRpcRequestParserController()) { - stateStack_.push(initialState_); + stateStack_.push(initialState); } XmlRpcRequestParserStateMachine::~XmlRpcRequestParserStateMachine() @@ -113,6 +101,154 @@ XmlRpcRequestParserStateMachine::~XmlRpcRequestParserStateMachine() 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 aria2 diff --git a/src/XmlRpcRequestParserStateMachine.h b/src/XmlRpcRequestParserStateMachine.h index 48137685..e0bc32c1 100644 --- a/src/XmlRpcRequestParserStateMachine.h +++ b/src/XmlRpcRequestParserStateMachine.h @@ -2,7 +2,7 @@ /* * 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 * 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 #define D_XML_RPC_REQUEST_PARSER_STATE_MACHINE_H -#include "common.h" +#include "ParserStateMachine.h" #include <string> -#include <map> #include <stack> -#include "XmlRpcRequestParserController.h" -#include "XmlRpcRequestParserStateImpl.h" -#include "ValueBase.h" +#include "SharedHandle.h" namespace aria2 { -namespace rpc { +class ValueBase; -class XmlRpcRequestParserStateMachine { -private: - XmlRpcRequestParserController* controller_; +namespace rpc { - std::stack<XmlRpcRequestParserState*> stateStack_; +class XmlRpcRequestParserController; +class XmlRpcRequestParserState; - 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_; +class XmlRpcRequestParserStateMachine : public ParserStateMachine { public: XmlRpcRequestParserStateMachine(); - - ~XmlRpcRequestParserStateMachine(); - - void beginElement(const char* name, - const std::map<std::string, std::string>& attrs) - { - stateStack_.top()->beginElement(this, name, attrs); - } - - void endElement(const char* name, const std::string& characters) - { - stateStack_.top()->endElement(this, name, characters); - stateStack_.pop(); - } - - void setMethodName(const std::string& methodName) - { - controller_->setMethodName(methodName); - } - - const std::string& getMethodName() const - { - return controller_->getMethodName(); - } - - void popArrayFrame() - { - controller_->popArrayFrame(); - } - - void popStructFrame() - { - controller_->popStructFrame(); - } - - void pushFrame() - { - controller_->pushFrame(); - } - - void setCurrentFrameValue(const SharedHandle<ValueBase>& value) - { - controller_->setCurrentFrameValue(value); - } - - 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_); } + virtual ~XmlRpcRequestParserStateMachine(); + + virtual bool needsCharactersBuffering() const; + virtual bool finished() const; + + virtual void beginElement + (const char* localname, + const char* prefix, + const char* nsUri, + const std::vector<XmlAttr>& attrs); + + virtual void endElement + (const char* localname, + const char* prefix, + const char* nsUri, + const std::string& characters); + + void setMethodName(const std::string& methodName); + const std::string& getMethodName() const; + void popArrayFrame(); + void popStructFrame(); + void pushFrame(); + void setCurrentFrameValue(const SharedHandle<ValueBase>& value); + const SharedHandle<ValueBase>& getCurrentFrameValue() const; + void setCurrentFrameName(const std::string& name); + + void pushUnknownElementState(); + void pushMethodCallState(); + void pushMethodNameState(); + void pushParamsState(); + void pushParamState(); + void pushValueState(); + void pushIntState(); + void pushStringState(); + void pushBase64State(); + void pushStructState(); + void pushMemberState(); + void pushNameState(); + void pushArrayState(); + void pushDataState(); + void pushArrayValueState(); +private: + std::stack<XmlRpcRequestParserState*> stateStack_; + XmlRpcRequestParserController* controller_; }; } // namespace rpc diff --git a/src/ExpatXmlRpcRequestProcessor.h b/src/rpc_helper.cc index e61f1d3d..d8d92acb 100644 --- a/src/ExpatXmlRpcRequestProcessor.h +++ b/src/rpc_helper.cc @@ -2,7 +2,7 @@ /* * 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 * 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. */ /* copyright --> */ -#ifndef D_EXPAT_XML_RPC_REQUEST_PROCESSOR_H -#define D_EXPAT_XML_RPC_REQUEST_PROCESSOR_H - -#include "common.h" - -#include <string> - -#include "SharedHandle.h" +#include "rpc_helper.h" +#include "XmlParser.h" #include "RpcRequest.h" +#include "XmlRpcRequestParserStateMachine.h" +#include "message.h" +#include "DlAbortEx.h" namespace aria2 { namespace rpc { -class XmlRpcRequestParserStateMachine; - -class XmlRpcRequestProcessor { -private: - SharedHandle<XmlRpcRequestParserStateMachine> stm_; -public: - RpcRequest parseMemory(const std::string& xml); -}; +#ifdef ENABLE_XML_RPC +RpcRequest xmlParseMemory(const char* xml, size_t size) +{ + XmlRpcRequestParserStateMachine psm; + if(!XmlParser(&psm).parseMemory(xml, size)) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST); + } + 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 aria2 - -#endif // D_EXPAT_XML_RPC_REQUEST_PROCESSOR_H diff --git a/src/XmlRpcRequestProcessor.h b/src/rpc_helper.h index 7b8bb17b..a4abae5c 100644 --- a/src/XmlRpcRequestProcessor.h +++ b/src/rpc_helper.h @@ -2,7 +2,7 @@ /* * 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 * 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. */ /* copyright --> */ -#ifndef D_XML_RPC_REQUEST_PROCESSOR_H -#define D_XML_RPC_REQUEST_PROCESSOR_H +#ifndef D_RPC_HELPER_H +#define D_RPC_HELPER_H #include "common.h" -#ifdef HAVE_LIBXML2 -# include "Xml2XmlRpcRequestProcessor.h" -#elif HAVE_LIBEXPAT -# include "ExpatXmlRpcRequestProcessor.h" -#endif // HAVE_LIBEXPAT +#include <cstdlib> -#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 diff --git a/test/Makefile.am b/test/Makefile.am index a078ce95..b0bcab2d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -79,11 +79,11 @@ aria2c_SOURCES = AllTest.cc\ BufferedFileTest.cc\ GeomStreamPieceSelectorTest.cc\ SegListTest.cc\ - ParamedStringTest.cc + ParamedStringTest.cc\ + RpcHelperTest.cc if ENABLE_XML_RPC -aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\ - XmlRpcRequestProcessorTest.cc +aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc endif # ENABLE_XML_RPC if HAVE_SOME_FALLOCATE diff --git a/test/RpcHelperTest.cc b/test/RpcHelperTest.cc new file mode 100644 index 00000000..8f04c434 --- /dev/null +++ b/test/RpcHelperTest.cc @@ -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 diff --git a/test/XmlRpcRequestProcessorTest.cc b/test/XmlRpcRequestProcessorTest.cc deleted file mode 100644 index 84a1a853..00000000 --- a/test/XmlRpcRequestProcessorTest.cc +++ /dev/null @@ -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 |
