]> git.stg.codes - stg.git/blob - projects/sgconf/xml.cpp
ec8b9178a06305891cdca5c3ad84fa9503500d32
[stg.git] / projects / sgconf / xml.cpp
1 #include "xml.h"
2
3 #include "config.h"
4
5 #include "stg/servconf.h"
6
7 #include <iostream>
8
9 #include <expat.h>
10
11 namespace
12 {
13
14 struct ParserState
15 {
16 size_t level;
17 };
18
19 std::string Indent(size_t level)
20 {
21 return std::string(level * 4, ' ');
22 }
23
24 std::string PrintAttr(const char ** attr)
25 {
26 std::string res;
27 if (attr == NULL)
28     return res;
29 while (*attr)
30     {
31     if (*(attr + 1) == NULL)
32         return res;
33     res += std::string(" ") + *attr + "=\"" + *(attr + 1) + "\"";
34     ++attr; ++attr;
35     }
36 return res;
37 }
38
39 void Start(void * data, const char * el, const char ** attr)
40 {
41 ParserState * state = static_cast<ParserState *>(data);
42 if (el != NULL)
43     std::cout << Indent(state->level) << "<" << el << PrintAttr(attr) << ">\n";
44 ++state->level;
45 }
46
47 void End(void * data, const char * el)
48 {
49 ParserState * state = static_cast<ParserState *>(data);
50 --state->level;
51 if (el != NULL)
52     std::cout << Indent(state->level) << "</" << el << ">\n";
53 }
54
55 void RawXMLCallback(bool result, const std::string & reason, const std::string & response, void * /*data*/)
56 {
57 if (!result)
58     {
59     std::cerr << "Failed to get raw XML response. Reason: '" << reason << "'." << std::endl;
60     return;
61     }
62 SGCONF::PrintXML(response);
63 }
64
65 }
66
67 void SGCONF::PrintXML(const std::string& xml)
68 {
69 ParserState state = { 0 };
70
71 XML_Parser parser = XML_ParserCreate(NULL);
72 XML_ParserReset(parser, NULL);
73 XML_SetElementHandler(parser, Start, End);
74 XML_SetUserData(parser, &state);
75
76 if (XML_Parse(parser, xml.c_str(), xml.length(), true) == XML_STATUS_ERROR)
77     std::cerr << "XML parse error at line " << XML_GetCurrentLineNumber(parser)
78               << ": '" << XML_ErrorString(XML_GetErrorCode(parser)) << "'"
79               << std::endl;
80
81 XML_ParserFree(parser);
82 }
83
84 bool SGCONF::RawXMLFunction(const SGCONF::CONFIG & config,
85                             const std::string & arg,
86                             const std::map<std::string, std::string> & /*options*/)
87 {
88     STG::SERVCONF proto(config.server.data(),
89                         config.port.data(),
90                         config.userName.data(),
91                         config.userPass.data());
92     return proto.RawXML(arg, RawXMLCallback, NULL) == STG::st_ok;
93 }