]> git.stg.codes - stg.git/blob - projects/sgconf/xml.cpp
Implemented raw XML API for sgconf.
[stg.git] / projects / sgconf / xml.cpp
1 #include "xml.h"
2
3 #include <iostream>
4
5 #include <expat.h>
6
7 namespace
8 {
9
10 struct ParserState
11 {
12 size_t level;
13 };
14
15 std::string Indent(size_t level)
16 {
17 return std::string(level * 4, ' ');
18 }
19
20 std::string PrintAttr(const char ** attr)
21 {
22 std::string res;
23 if (attr == NULL)
24     return res;
25 while (*attr)
26     {
27     if (*(attr + 1) == NULL)
28         return res;
29     res += std::string(" ") + *attr + "=\"" + *(attr + 1) + "\"";
30     ++attr; ++attr;
31     }
32 return res;
33 }
34
35 void Start(void * data, const char * el, const char ** attr)
36 {
37 ParserState * state = static_cast<ParserState *>(data);
38 if (el != NULL)
39     std::cout << Indent(state->level) << "<" << el << PrintAttr(attr) << ">\n";
40 ++state->level;
41 }
42
43 void End(void * data, const char * el)
44 {
45 ParserState * state = static_cast<ParserState *>(data);
46 --state->level;
47 if (el != NULL)
48     std::cout << Indent(state->level) << "</" << el << ">\n";
49 }
50
51 }
52
53 void SGCONF::PrintXML(const std::string& xml)
54 {
55 ParserState state = { 0 };
56
57 XML_Parser parser = XML_ParserCreate(NULL);
58 XML_ParserReset(parser, NULL);
59 XML_SetElementHandler(parser, Start, End);
60 XML_SetUserData(parser, &state);
61
62 if (XML_Parse(parser, xml.c_str(), xml.length(), true) == XML_STATUS_ERROR)
63     std::cerr << "XML parse error at line " << XML_GetCurrentLineNumber(parser)
64               << ": '" << XML_ErrorString(XML_GetErrorCode(parser)) << "'"
65               << std::endl;
66
67 XML_ParserFree(parser);
68 }