X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/8c6fa3fbaccc22127280bf77a48fab5a3ee0716e..46b0747592074017ff0ea4b33d4a7194235886e5:/sgconf/xml.cpp diff --git a/sgconf/xml.cpp b/sgconf/xml.cpp new file mode 100644 index 00000000..abf2ccc6 --- /dev/null +++ b/sgconf/xml.cpp @@ -0,0 +1,105 @@ +#include "xml.h" + +#include "api_action.h" +#include "options.h" +#include "config.h" + +#include "stg/servconf.h" + +#include +#include +#include + +#include + +namespace +{ + +struct ParserState +{ +size_t level; +}; + +std::string Indent(size_t level) +{ +return std::string(level * 4, ' '); +} + +std::string PrintAttr(const char ** attr) +{ +std::string res; +if (attr == NULL) + return res; +while (*attr) + { + if (*(attr + 1) == NULL) + return res; + res += std::string(" ") + *attr + "=\"" + *(attr + 1) + "\""; + ++attr; ++attr; + } +return res; +} + +void Start(void * data, const char * el, const char ** attr) +{ +ParserState * state = static_cast(data); +if (el != NULL) + std::cout << Indent(state->level) << "<" << el << PrintAttr(attr) << ">\n"; +++state->level; +} + +void End(void * data, const char * el) +{ +ParserState * state = static_cast(data); +--state->level; +if (el != NULL) + std::cout << Indent(state->level) << "\n"; +} + +void PrintXML(const std::string& xml) +{ +ParserState state = { 0 }; + +XML_Parser parser = XML_ParserCreate(NULL); +XML_ParserReset(parser, NULL); +XML_SetElementHandler(parser, Start, End); +XML_SetUserData(parser, &state); + +if (XML_Parse(parser, xml.c_str(), xml.length(), true) == XML_STATUS_ERROR) + std::cerr << "XML parse error at line " << XML_GetCurrentLineNumber(parser) + << ": '" << XML_ErrorString(XML_GetErrorCode(parser)) << "'" + << std::endl; + +XML_ParserFree(parser); +} + +void RawXMLCallback(bool result, const std::string & reason, const std::string & response, void * /*data*/) +{ +if (!result) + { + std::cerr << "Failed to get raw XML response. Reason: '" << reason << "'." << std::endl; + return; + } +PrintXML(response); +} + +bool RawXMLFunction(const SGCONF::CONFIG & config, + const std::string & arg, + const std::map & /*options*/) +{ +STG::SERVCONF proto(config.server.data(), + config.port.data(), + config.localAddress.data(), + config.localPort.data(), + config.userName.data(), + config.userPass.data()); +return proto.RawXML(arg, RawXMLCallback, NULL) == STG::st_ok; +} + +} + +void SGCONF::AppendXMLOptionBlock(COMMANDS & commands, OPTION_BLOCKS & blocks) +{ +blocks.Add("Raw XML") + .Add("r", "raw", SGCONF::MakeAPIAction(commands, "", RawXMLFunction), "\tmake raw XML request"); +}