summaryrefslogtreecommitdiff
path: root/src/xml.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-03-09 22:26:25 +0100
committerThomas Schmucker <ts@its1.de>2025-03-09 22:26:25 +0100
commit0cf833840b19e603f480dead5ca211f947503f9b (patch)
tree9b146c5644e1bb93ed0307275a6930bffe11d0ad /src/xml.cpp
downloadexpat++-0cf833840b19e603f480dead5ca211f947503f9b.tar.gz
expat++-0cf833840b19e603f480dead5ca211f947503f9b.tar.bz2
expat++-0cf833840b19e603f480dead5ca211f947503f9b.zip
Initial commit
Diffstat (limited to 'src/xml.cpp')
-rw-r--r--src/xml.cpp75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/xml.cpp b/src/xml.cpp
new file mode 100644
index 0000000..44b423a
--- /dev/null
+++ b/src/xml.cpp
@@ -0,0 +1,75 @@
1// Standard C++
2#include <memory>
3#include <sstream>
4
5// Projekt
6#include "xml.hpp"
7
8// Expat XML Parser
9#define XML_STATIC // force static linkage
10#include "expat.h"
11
12using namespace std;
13
14void
15XML::parse(istream& in)
16{
17 unique_ptr<XML_ParserStruct, decltype(&XML_ParserFree)> parser(XML_ParserCreate(nullptr), XML_ParserFree);
18
19 // setup expat
20 XML_SetUserData(parser.get(), this);
21 XML_SetElementHandler(parser.get(), tag_start, tag_end);
22 XML_SetCdataSectionHandler(parser.get(), cdata_start, cdata_end);
23 XML_SetCharacterDataHandler(parser.get(), data);
24
25 char buffer[2048];
26 for ( bool done = false; !done ; ) {
27 in.read(buffer, sizeof buffer);
28 done = (in.gcount() < sizeof buffer);
29
30 if ( XML_Parse(parser.get(), buffer, static_cast<int>(in.gcount()), done) != XML_STATUS_OK ) {
31 stringstream msg;
32
33 msg << XML_ErrorString(XML_GetErrorCode(parser.get()));
34 msg << " in line " << XML_GetCurrentLineNumber(parser.get());
35
36 throw runtime_error( msg.str() );
37 }
38 }
39}
40
41void
42XML::tag_start(void* me, const char* name, const char* attr[])
43{
44 vector<pair<string, string>> attr_temp;
45
46 for ( size_t i = 0; attr[i]; i += 2 )
47 attr_temp.push_back( make_pair<string, string>(attr[i], attr[i+1]) );
48
49 reinterpret_cast<XML*>(me)->handle_start(name, attr_temp);
50}
51
52void
53XML::tag_end(void* me, const char* name)
54{
55 reinterpret_cast<XML*>(me)->handle_end(name);
56}
57
58void
59XML::cdata_start(void* me)
60{
61 reinterpret_cast<XML*>(me)->handle_cdata_start();
62}
63
64void
65XML::cdata_end(void* me)
66{
67 reinterpret_cast<XML*>(me)->handle_cdata_end();
68}
69
70void
71XML::data(void* me, const char* dat, int len)
72{
73 reinterpret_cast<XML*>(me)->handle_data(vector<char>(dat, dat+len));
74}
75