# HG changeset patch # User František Kučera # Date 1603756794 -3600 # Node ID 3b197bf7a2314e5966f7062a2f2bdd3083a15429 # Parent 66db59d77033fd43336e6529aeaf4edea4da14dd raw YAML events to DOM diff -r 66db59d77033 -r 3b197bf7a231 src/CMakeLists.txt --- a/src/CMakeLists.txt Sun Oct 25 21:55:20 2020 +0100 +++ b/src/CMakeLists.txt Tue Oct 27 00:59:54 2020 +0100 @@ -17,7 +17,7 @@ # Relpipe libraries: INCLUDE(FindPkgConfig) -pkg_check_modules (RELPIPE_LIBS relpipe-lib-writer.cpp relpipe-lib-cli.cpp libxml++-2.6) +pkg_check_modules (RELPIPE_LIBS relpipe-lib-writer.cpp relpipe-lib-cli.cpp libxml++-2.6 yaml-0.1) include_directories(${RELPIPE_LIBS_INCLUDE_DIRS}) link_directories(${RELPIPE_LIBS_LIBRARY_DIRS}) diff -r 66db59d77033 -r 3b197bf7a231 src/XMLDocumentConstructor.h --- a/src/XMLDocumentConstructor.h Sun Oct 25 21:55:20 2020 +0100 +++ b/src/XMLDocumentConstructor.h Tue Oct 27 00:59:54 2020 +0100 @@ -20,19 +20,90 @@ namespace in { namespace xmltable { +#include + #include +#include class XMLDocumentConstructor { private: std::istream* input = nullptr; xmlpp::DomParser* parser = nullptr; + yaml_parser_t yamlParser; + + 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. + */ + const char* y2x(yaml_char_t* value) { + return value ? (const char*) value : ""; + } + public: XMLDocumentConstructor(std::istream* input, xmlpp::DomParser* parser) : input(input), parser(parser) { + yaml_parser_initialize(&yamlParser); + yaml_parser_set_input(&yamlParser, readFromInput, (void*) this); + } + + virtual ~XMLDocumentConstructor() { + yaml_parser_delete(&yamlParser); } void process() { - parser->parse_stream(*input); + xmlpp::Element* root = parser->get_document()->create_root_node("yaml"); + + while (true) { + yaml_event_t event; + + if (!yaml_parser_parse(&yamlParser, &event)) { + // FIXME: throw exception + std::wcerr << L"YAML error" << std::endl; + return; + } + + + if (event.type == YAML_STREAM_END_EVENT) { + xmlpp::Element* e = root->add_child("YAML_STREAM_END_EVENT"); + yaml_event_delete(&event); + break; + } else if (event.type == YAML_STREAM_START_EVENT) { + xmlpp::Element* e = root->add_child("YAML_STREAM_START_EVENT"); + } else if (event.type == YAML_NO_EVENT) { + xmlpp::Element* e = root->add_child("YAML_NO_EVENT"); + } else if (event.type == YAML_DOCUMENT_START_EVENT) { + xmlpp::Element* e = root->add_child("YAML_DOCUMENT_START_EVENT"); + } else if (event.type == YAML_DOCUMENT_END_EVENT) { + xmlpp::Element* e = root->add_child("YAML_DOCUMENT_END_EVENT"); + } else if (event.type == YAML_ALIAS_EVENT) { + xmlpp::Element* e = root->add_child("YAML_ALIAS_EVENT"); + } 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)); + } 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)); + } else if (event.type == YAML_SEQUENCE_END_EVENT) { + xmlpp::Element* e = root->add_child("YAML_SEQUENCE_END_EVENT"); + } else if (event.type == YAML_MAPPING_START_EVENT) { + xmlpp::Element* e = root->add_child("YAML_MAPPING_START_EVENT"); + } else if (event.type == YAML_MAPPING_END_EVENT) { + xmlpp::Element* e = root->add_child("YAML_MAPPING_END_EVENT"); + } + + yaml_event_delete(&event); + } + + } };