# HG changeset patch # User František Kučera # Date 1603834790 -3600 # Node ID 75c6685cceb9ee25e47e68f424ab7b44ef58b3f1 # Parent 3b197bf7a2314e5966f7062a2f2bdd3083a15429 YAML data to DOM: first dirty version with debug diff -r 3b197bf7a231 -r 75c6685cceb9 src/XMLDocumentConstructor.h --- a/src/XMLDocumentConstructor.h Tue Oct 27 00:59:54 2020 +0100 +++ b/src/XMLDocumentConstructor.h Tue Oct 27 22:39:50 2020 +0100 @@ -21,6 +21,7 @@ namespace xmltable { #include +#include #include #include @@ -31,13 +32,23 @@ xmlpp::DomParser* parser = nullptr; yaml_parser_t yamlParser; + enum class Mode { + ROOT, + SEQUENCE, + MAPPING, + MAP_KEY + }; + + xmlpp::Element* current; + std::vector mode; + static int readFromInput(void* instance, unsigned char* buffer, size_t size, size_t* length) { std::istream* input = ((XMLDocumentConstructor*) instance)->input; input->read((char*) buffer, size); *length = input->gcount(); return (input->good() || input->eof()) ? 1 : 0; } - + /** * Both YAML and XML strings are in UTF-8. */ @@ -45,6 +56,16 @@ return value ? (const char*) value : ""; } + const std::string y2xname(yaml_char_t* value) { + // FIXME: escaping, assure valid XML names + //return std::string("name_") + y2x(value); + return y2x(value); + } + + xmlpp::Element* parentOrSelf(xmlpp::Element* current) { + return current->get_parent() == nullptr ? current : current->get_parent(); + } + public: XMLDocumentConstructor(std::istream* input, xmlpp::DomParser* parser) : input(input), parser(parser) { @@ -57,7 +78,8 @@ } void process() { - xmlpp::Element* root = parser->get_document()->create_root_node("yaml"); + current = parser->get_document()->create_root_node("yaml"); + mode.push_back(Mode::ROOT); while (true) { yaml_event_t event; @@ -70,34 +92,66 @@ if (event.type == YAML_STREAM_END_EVENT) { - xmlpp::Element* e = root->add_child("YAML_STREAM_END_EVENT"); + std::cerr << "YAML_STREAM_END_EVENT" << std::endl; yaml_event_delete(&event); break; } else if (event.type == YAML_STREAM_START_EVENT) { - xmlpp::Element* e = root->add_child("YAML_STREAM_START_EVENT"); + std::cerr << "YAML_STREAM_START_EVENT" << std::endl; } else if (event.type == YAML_NO_EVENT) { - xmlpp::Element* e = root->add_child("YAML_NO_EVENT"); + std::cerr << "YAML_NO_EVENT" << std::endl; + current->add_child("null"); // TODO: null? } else if (event.type == YAML_DOCUMENT_START_EVENT) { - xmlpp::Element* e = root->add_child("YAML_DOCUMENT_START_EVENT"); + std::cerr << "YAML_DOCUMENT_START_EVENT" << std::endl; } else if (event.type == YAML_DOCUMENT_END_EVENT) { - xmlpp::Element* e = root->add_child("YAML_DOCUMENT_END_EVENT"); + std::cerr << "YAML_DOCUMENT_END_EVENT" << std::endl; } else if (event.type == YAML_ALIAS_EVENT) { - xmlpp::Element* e = root->add_child("YAML_ALIAS_EVENT"); + std::cerr << "YAML_ALIAS_EVENT" << std::endl; + // TODO: alias? } else if (event.type == YAML_SCALAR_EVENT) { - xmlpp::Element* e = root->add_child("YAML_SCALAR_EVENT"); - e->set_attribute("value", y2x(event.data.scalar.value)); - e->set_attribute("anchor", y2x(event.data.scalar.anchor)); - e->set_attribute("tag", y2x(event.data.scalar.tag)); - e->set_attribute("style", std::to_string(event.data.scalar.style)); + if (mode.back() == Mode::SEQUENCE) { + std::cerr << "YAML_SCALAR_EVENT: Mode::SEQUENCE: " << event.data.scalar.value << std::endl; + current->add_child("item")->add_child_text(y2x(event.data.scalar.value)); + } else if (mode.back() == Mode::MAPPING) { + std::cerr << "YAML_SCALAR_EVENT: Mode::MAPPING: " << event.data.scalar.value << std::endl; + current = current->add_child(y2xname(event.data.scalar.value)); + mode.push_back(Mode::MAP_KEY); + } else if (mode.back() == Mode::MAP_KEY) { + std::cerr << "YAML_SCALAR_EVENT: Mode::MAP_KEY: " << event.data.scalar.value << std::endl; + current->add_child_text(y2x(event.data.scalar.value)); + current = parentOrSelf(current); + mode.pop_back(); + } else { + std::cerr << "YAML_SCALAR_EVENT: ???" << std::endl; + } + } else if (event.type == YAML_SEQUENCE_START_EVENT) { - xmlpp::Element* e = root->add_child("YAML_SEQUENCE_START_EVENT"); - e->set_attribute("style", std::to_string(event.data.sequence_start.style)); + std::cerr << "YAML_SEQUENCE_START_EVENT" << std::endl; + if (mode.back() == Mode::MAP_KEY) mode.pop_back(); + mode.push_back(Mode::SEQUENCE); } else if (event.type == YAML_SEQUENCE_END_EVENT) { - xmlpp::Element* e = root->add_child("YAML_SEQUENCE_END_EVENT"); + std::cerr << "YAML_SEQUENCE_END_EVENT" << std::endl; + current = parentOrSelf(current); + mode.pop_back(); // TODO: assert sequence? } else if (event.type == YAML_MAPPING_START_EVENT) { - xmlpp::Element* e = root->add_child("YAML_MAPPING_START_EVENT"); + + if (mode.back() == Mode::SEQUENCE) { + std::cerr << "YAML_MAPPING_START_EVENT: Mode::SEQUENCE" << std::endl; + current = current->add_child("item"); + } else if (mode.back() == Mode::MAP_KEY) { + std::cerr << "YAML_MAPPING_START_EVENT: Mode::MAP_KEY" << std::endl; + mode.pop_back(); + } else { + std::cerr << "YAML_MAPPING_START_EVENT: Mode::?" << std::endl; + // TODO: map might be a key of another map → wrap/nest + } + + mode.push_back(Mode::MAPPING); } else if (event.type == YAML_MAPPING_END_EVENT) { - xmlpp::Element* e = root->add_child("YAML_MAPPING_END_EVENT"); + std::cerr << "YAML_MAPPING_END_EVENT" << std::endl; + current = parentOrSelf(current); + mode.pop_back(); // TODO: assert map? + } else { + std::cerr << "???" << std::endl; } yaml_event_delete(&event); @@ -109,4 +163,4 @@ } } -} \ No newline at end of file +}