/* */ #include "ExpatXmlRpcRequestProcessor.h" #include #include #include "XmlRpcRequestParserStateMachine.h" #include "Util.h" #include "DlAbortEx.h" #include "message.h" namespace aria2 { namespace xmlrpc { struct SessionData { XmlRpcRequestParserStateMachine* _stm; std::stack _charactersStack; SessionData(XmlRpcRequestParserStateMachine* stm):_stm(stm) {} }; static void mlStartElement(void* userData, const char* name, const char** attrs) { SessionData* sd = reinterpret_cast(userData); std::map attrmap; if(attrs) { const char** p = attrs; while(*p != 0) { std::string name = *p++; if(*p == 0) { break; } std::string value = Util::trim(*p++); attrmap[name] = value; } } sd->_stm->beginElement(name, attrmap); if(sd->_stm->needsCharactersBuffering()) { sd->_charactersStack.push(std::string()); } } static void mlEndElement(void* userData, const char* name) { SessionData* sd = reinterpret_cast(userData); std::string characters; if(sd->_stm->needsCharactersBuffering()) { characters = Util::trim(sd->_charactersStack.top()); sd->_charactersStack.pop(); } sd->_stm->endElement(name, characters); } static void mlCharacters(void* userData, const char* ch, int len) { SessionData* sd = reinterpret_cast(userData); if(sd->_stm->needsCharactersBuffering()) { sd->_charactersStack.top() += std::string(&ch[0], &ch[len]); } } XmlRpcRequest XmlRpcRequestProcessor::parseMemory(const std::string& xml) { _stm.reset(new XmlRpcRequestParserStateMachine()); SharedHandle 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); } return XmlRpcRequest(_stm->getMethodName(), _stm->getCurrentFrameValue()); } } // namespace xmlrpc } // namespace aria2