From 0cf833840b19e603f480dead5ca211f947503f9b Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Sun, 9 Mar 2025 22:26:25 +0100 Subject: Initial commit --- src/xml.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/xml.cpp (limited to 'src/xml.cpp') 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 @@ +// Standard C++ +#include +#include + +// Projekt +#include "xml.hpp" + +// Expat XML Parser +#define XML_STATIC // force static linkage +#include "expat.h" + +using namespace std; + +void +XML::parse(istream& in) +{ + unique_ptr parser(XML_ParserCreate(nullptr), XML_ParserFree); + + // setup expat + XML_SetUserData(parser.get(), this); + XML_SetElementHandler(parser.get(), tag_start, tag_end); + XML_SetCdataSectionHandler(parser.get(), cdata_start, cdata_end); + XML_SetCharacterDataHandler(parser.get(), data); + + char buffer[2048]; + for ( bool done = false; !done ; ) { + in.read(buffer, sizeof buffer); + done = (in.gcount() < sizeof buffer); + + if ( XML_Parse(parser.get(), buffer, static_cast(in.gcount()), done) != XML_STATUS_OK ) { + stringstream msg; + + msg << XML_ErrorString(XML_GetErrorCode(parser.get())); + msg << " in line " << XML_GetCurrentLineNumber(parser.get()); + + throw runtime_error( msg.str() ); + } + } +} + +void +XML::tag_start(void* me, const char* name, const char* attr[]) +{ + vector> attr_temp; + + for ( size_t i = 0; attr[i]; i += 2 ) + attr_temp.push_back( make_pair(attr[i], attr[i+1]) ); + + reinterpret_cast(me)->handle_start(name, attr_temp); +} + +void +XML::tag_end(void* me, const char* name) +{ + reinterpret_cast(me)->handle_end(name); +} + +void +XML::cdata_start(void* me) +{ + reinterpret_cast(me)->handle_cdata_start(); +} + +void +XML::cdata_end(void* me) +{ + reinterpret_cast(me)->handle_cdata_end(); +} + +void +XML::data(void* me, const char* dat, int len) +{ + reinterpret_cast(me)->handle_data(vector(dat, dat+len)); +} + -- cgit v1.3