/* */ #include "Xml2XmlRpcRequestProcessor.h" #include #include #include "XmlRpcRequestParserStateMachine.h" #include "util.h" #include "DlAbortEx.h" #include "message.h" namespace aria2 { namespace rpc { namespace { struct SessionData { XmlRpcRequestParserStateMachine* stm_; std::stack charactersStack_; SessionData(XmlRpcRequestParserStateMachine* stm):stm_(stm) {} }; } // namespace namespace { void mlStartElement(void* userData, const xmlChar* name, const xmlChar** attrs) { SessionData* sd = reinterpret_cast(userData); std::map attrmap; if(attrs) { const xmlChar** p = attrs; while(*p != 0) { std::string name = reinterpret_cast(*p); ++p; if(*p == 0) { break; } std::string value = util::strip(reinterpret_cast(*p)); ++p; attrmap[name] = value; } } sd->stm_->beginElement(reinterpret_cast(name), attrmap); if(sd->stm_->needsCharactersBuffering()) { sd->charactersStack_.push(std::string()); } } } // namespace namespace { void mlEndElement(void* userData, const xmlChar* name) { SessionData* sd = reinterpret_cast(userData); std::string characters; if(sd->stm_->needsCharactersBuffering()) { characters = util::strip(sd->charactersStack_.top()); sd->charactersStack_.pop(); } sd->stm_->endElement(reinterpret_cast(name), characters); } } // namespace namespace { void mlCharacters(void* userData, const xmlChar* ch, int len) { SessionData* sd = reinterpret_cast(userData); if(sd->stm_->needsCharactersBuffering()) { sd->charactersStack_.top() += std::string(&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(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(stm_->getCurrentFrameValue())) { throw DL_ABORT_EX("Bad XML-RPC parameter list"); } return RpcRequest(stm_->getMethodName(), static_pointer_cast(stm_->getCurrentFrameValue())); } } // namespace rpc } // namespace aria2