/* */ #include "XmlRpcRequestParserStateImpl.h" #include "XmlRpcRequestParserStateMachine.h" #include "XmlRpcElements.h" #include "RecoverableException.h" #include "util.h" #include "base64.h" namespace aria2 { namespace rpc { // InitialXmlRpcRequestParserState void InitialXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::METHOD_CALL) { stm->pushMethodCallState(); } else { stm->pushUnknownElementState(); } } void InitialXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) {} // UnknownElementXmlRpcRequestParserState void UnknownElementXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { stm->pushUnknownElementState(); } // MethodCallXmlRpcRequestParserState void MethodCallXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::METHOD_NAME) { stm->pushMethodNameState(); } else if(name == elements::A2_PARAMS) { stm->setCurrentFrameValue(List::g()); stm->pushParamsState(); } else { stm->pushUnknownElementState(); } } // MethodNameXmlRpcRequestParserState void MethodNameXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { stm->pushUnknownElementState(); } void MethodNameXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { stm->setMethodName(characters); } // ParamsXmlRpcRequestParserState void ParamsXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::PARAM) { stm->pushFrame(); stm->pushParamState(); } else { stm->pushUnknownElementState(); } } // ParamXmlRpcRequestParserState void ParamXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::VALUE) { stm->pushValueState(); } else { stm->pushUnknownElementState(); } } void ParamXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { stm->popArrayFrame(); } // ValueXmlRpcRequestParserState void ValueXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& 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(); } else { stm->pushUnknownElementState(); } } void ValueXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, 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)); } } // IntXmlRpcRequestParserState void IntXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { stm->pushUnknownElementState(); } void IntXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { try { int64_t value = util::parseLLInt(characters.begin(), characters.end()); stm->setCurrentFrameValue(Integer::g(value)); } catch(RecoverableException& e) { // nothing to do here: We just leave current frame value to null. } } // StringXmlRpcRequestParserState void StringXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { stm->pushUnknownElementState(); } void StringXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { stm->setCurrentFrameValue(String::g(characters)); } // Base64XmlRpcRequestParserState void Base64XmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { stm->pushUnknownElementState(); } void Base64XmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { stm->setCurrentFrameValue (String::g(base64::decode(characters.begin(), characters.end()))); } // StructXmlRpcRequestParserState void StructXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::MEMBER) { stm->pushFrame(); stm->pushMemberState(); } else { stm->pushUnknownElementState(); } } // MemberXmlRpcRequestParserState void MemberXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::NAME) { stm->pushNameState(); } else if(name == elements::VALUE) { stm->pushValueState(); } else { stm->pushUnknownElementState(); } } void MemberXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { stm->popStructFrame(); } // NameXmlRpcRequestParserState void NameXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { stm->pushUnknownElementState(); } void NameXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { stm->setCurrentFrameName(characters); } // ArrayXmlRpcRequestParserState void ArrayXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::DATA) { stm->pushDataState(); } else { stm->pushUnknownElementState(); } } // DataXmlRpcRequestParserState void DataXmlRpcRequestParserState::beginElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::map& attrs) { if(name == elements::VALUE) { stm->pushFrame(); stm->pushArrayValueState(); } else { stm->pushUnknownElementState(); } } // ArrayValueXmlRpcRequestParserState void ArrayValueXmlRpcRequestParserState::endElement (XmlRpcRequestParserStateMachine* stm, const char* name, const std::string& characters) { ValueXmlRpcRequestParserState::endElement(stm, name, characters); stm->popArrayFrame(); } } // namespace rpc } // namespace aria2