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