# HG changeset patch # User František Kučera # Date 1606069542 -3600 # Node ID 45c06bdf90457cadfb2879ab39bccb6c65984532 # Parent 786977554fc389913a9bac55ad2e17a03d909cd3 produce hierarchical structure of INI sections and entries diff -r 786977554fc3 -r 45c06bdf9045 src/XMLDocumentConstructor.h --- a/src/XMLDocumentConstructor.h Sun Nov 22 17:39:10 2020 +0100 +++ b/src/XMLDocumentConstructor.h Sun Nov 22 19:25:42 2020 +0100 @@ -16,6 +16,7 @@ */ #pragma once +#include #include #include "lib/INIReader.h" @@ -28,7 +29,8 @@ class HierarchicalINIContentHandler : public INIContentHandler { private: xmlpp::DomParser* domParser; - wstring_convert < codecvt_utf8> convertor; // INI parser works with UTF-8 + XMLNameCodec nameCodec; + xmlpp::Element* currentSection = nullptr; public: HierarchicalINIContentHandler(xmlpp::DomParser* domParser) : domParser(domParser) { @@ -38,40 +40,43 @@ } void startDocument() override { - domParser->get_document()->create_root_node("ini"); - domParser->get_document()->get_root_node()->add_child("startDocument"); - // there should be only one document + if (currentSection) throw std::out_of_range("Lunatic INI parser send us multiple documents."); + currentSection = domParser->get_document()->create_root_node("ini"); }; void endDocument() override { - domParser->get_document()->get_root_node()->add_child("endDocument"); }; void startSection(const SectionStartEvent& event) override { - xmlpp::Element* node = domParser->get_document()->get_root_node()->add_child("startSection"); - node->add_child("name")->add_child_text(event.name); - node->add_child("comment")->add_child_text(event.comment); - node->add_child("line-number")->add_child_text(std::to_string(event.lineNumber)); - node->add_child("event-number")->add_child_text(std::to_string(event.eventNumber)); + currentSection = currentSection->add_child(nameCodec.encode(event.name)); + currentSection->set_attribute("type", "section"); + currentSection->set_attribute("name", event.name); + if (event.comment.size()) currentSection->set_attribute("comment", event.comment); + if (event.lineNumber >= 0) currentSection->set_attribute("line-number", std::to_string(event.lineNumber)); + if (event.eventNumber >= 0) currentSection->set_attribute("event-number", std::to_string(event.eventNumber)); }; void endSection() override { - domParser->get_document()->get_root_node()->add_child("endSection"); + currentSection = currentSection->get_parent(); + if (currentSection == nullptr) throw std::out_of_range("Lunatic INI parser tried to end a section without starting it before."); }; void entry(const EntryEvent& event) override { - xmlpp::Element* node = domParser->get_document()->get_root_node()->add_child("entry"); - node->add_child("key")->add_child_text(event.key); - node->add_child("sub-key")->add_child_text(event.subKey); - node->add_child("full-key")->add_child_text(event.fullKey); - node->add_child("value")->add_child_text(event.value); - node->add_child("comment")->add_child_text(event.comment); - node->add_child("line-number")->add_child_text(std::to_string(event.lineNumber)); - node->add_child("event-number")->add_child_text(std::to_string(event.eventNumber)); + xmlpp::Element* entry = currentSection->add_child(nameCodec.encode(event.fullKey)); + entry->set_attribute("type", "entry"); + entry->set_attribute("key", event.key); + entry->set_attribute("full-key", event.fullKey); + if (event.subKey.size()) entry->set_attribute("sub-key", event.subKey); + if (event.comment.size()) currentSection->set_attribute("comment", event.comment); + if (event.lineNumber >= 0) currentSection->set_attribute("line-number", std::to_string(event.lineNumber)); + if (event.eventNumber >= 0) currentSection->set_attribute("event-number", std::to_string(event.eventNumber)); + entry->add_child_text(event.value); }; }; +// TODO: support also other styles/mappings e.g.
and with INI names only in the XML attributes (and thus without @type="section|entry") + class XMLDocumentConstructor { private: std::istream* input = nullptr;