// 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)); }