From 4f3760fc3b647fa166da4ab777eb612b14ac500b Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Wed, 15 Jul 2026 21:05:19 +0200 Subject: Umbau auf modernes C++ --- src/xml.cpp | 50 ++++++++++++++++-------------- src/xml_test.cpp | 92 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 88 insertions(+), 54 deletions(-) (limited to 'src') 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 @@ // Standard C++ +#include #include #include +#include -// Projekt +// Project #include "xml.hpp" // Expat XML Parser -#define XML_STATIC // force static linkage #include "expat.h" using namespace std; void -XML::parse(istream& in) +XML::parse(istream& ins) { unique_ptr parser(XML_ParserCreate(nullptr), XML_ParserFree); @@ -22,54 +23,57 @@ XML::parse(istream& in) 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); + static const auto buffer_size = 2048; - if ( XML_Parse(parser.get(), buffer, static_cast(in.gcount()), done) != XML_STATUS_OK ) { + array buffer{}; + + for ( bool done = false; !done; ) { + ins.read(buffer.data(), buffer_size); + done = ins.gcount() < buffer_size; + + if ( XML_Parse(parser.get(), buffer.data(), static_cast(ins.gcount()), static_cast(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() ); + throw runtime_error(msg.str()); } } } void -XML::tag_start(void* me, const char* name, const char* attr[]) +XML::tag_start(void* self, const char* name, const char** attr) { - vector> attr_temp; + vector> attr_temp; - for ( size_t i = 0; attr[i]; i += 2 ) - attr_temp.push_back( make_pair(attr[i], attr[i+1]) ); + for ( auto i = 0; attr[i] != nullptr; i += 2 ) { + attr_temp.emplace_back(attr[i], attr[i + 1]); + } - reinterpret_cast(me)->handle_start(name, attr_temp); + static_cast(self)->handle_start(name, attr_temp); } void -XML::tag_end(void* me, const char* name) +XML::tag_end(void* self, const char* name) { - reinterpret_cast(me)->handle_end(name); + static_cast(self)->handle_end(name); } void -XML::cdata_start(void* me) +XML::cdata_start(void* self) { - reinterpret_cast(me)->handle_cdata_start(); + static_cast(self)->handle_cdata_start(); } void -XML::cdata_end(void* me) +XML::cdata_end(void* self) { - reinterpret_cast(me)->handle_cdata_end(); + static_cast(self)->handle_cdata_end(); } void -XML::data(void* me, const char* dat, int len) +XML::data(void* self, const char* dat, int len) { - reinterpret_cast(me)->handle_data(vector(dat, dat+len)); + static_cast(self)->handle_character_data({ dat, dat + len }); } - diff --git a/src/xml_test.cpp b/src/xml_test.cpp index 0af5b51..0b978a9 100644 --- a/src/xml_test.cpp +++ b/src/xml_test.cpp @@ -1,48 +1,78 @@ #include #include +#include using namespace std; #include "xml.hpp" class MyXML : public XML { - public: - explicit MyXML(ostream& out, size_t indent = 4) - : pout_(&out) - , depth_(0) - , indent_(indent) - { - } +public: + explicit MyXML(ostream& out, size_t indent = 4) + : pout_(&out) + , indent_(indent) + { + } - protected: - void handle_start(const string& name, const vector>& attr) - { - *pout_ << string(depth_++ * indent_, ' ') - << "<" << name; +protected: + void handle_start(string_view name, const vector>& attr) override + { + *pout_ << string(depth_++ * indent_, ' ') + << "<" << name; - auto it = cbegin(attr); - auto end = cend(attr); - if ( it != end ) { - *pout_ << " " << it->first << "=\"" << it->second << "\""; + auto start = cbegin(attr); + auto end = cend(attr); + if ( start != end ) { + *pout_ << " " << get<0>(*start) << "=\"" << get<1>(*start) << "\""; - ++it; // skip first Element - for ( ; it != end; ++it ) - *pout_ << ", " << it->first << "=\"" << it->second << "\""; + ++start; // skip first Element + for ( ; start != end; ++start ) { + *pout_ << ", " << get<0>(*start) << "=\"" << get<1>(*start) << "\""; } - - *pout_ << ">" << endl; } - void handle_end(const string& name) - { - *pout_ << string(--depth_ * indent_, ' ') - << "" - << endl; + *pout_ << ">" << '\n'; + } + + void handle_end(string_view name) override + { + *pout_ << string(--depth_ * indent_, ' ') + << "" + << '\n'; + } + void handle_cdata_start() override + { + *pout_ << string(depth_ * indent_, ' ') + << "" << '\n'; + } + + static bool contains_only_whitespace(span data) + { + return ranges::all_of(data, [](unsigned char chr) { + return std::isspace(chr); + }); + } + + void handle_character_data(span data) override + { + if ( contains_only_whitespace(data) ) { + return; } - private: - ostream* pout_; - size_t depth_; - size_t indent_; + *pout_ << string(depth_ * indent_, ' ') << "Data: "; + pout_->write(data.data(), static_cast(data.size())); + *pout_ << '\n'; + } + +private: + ostream* pout_; + size_t depth_{}; + size_t indent_; }; int @@ -53,6 +83,6 @@ main() myxml.parse(cin); } catch ( exception& e ) { - cerr << "Fehler: " << e.what() << endl; + cerr << "Fehler: " << e.what() << '\n'; } } -- cgit v1.3