--- 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 <stdexcept>
#include <libxml++-2.6/libxml++/libxml++.h>
#include "lib/INIReader.h"
@@ -28,7 +29,8 @@
class HierarchicalINIContentHandler : public INIContentHandler {
private:
xmlpp::DomParser* domParser;
- wstring_convert < codecvt_utf8<wchar_t>> 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. <section/> and <entry/> with INI names only in the XML attributes (and thus without @type="section|entry")
+
class XMLDocumentConstructor {
private:
std::istream* input = nullptr;